bmizerany-sinatra 0.3.2 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/AUTHORS +40 -0
  2. data/CHANGES +174 -0
  3. data/README.rdoc +138 -116
  4. data/Rakefile +27 -9
  5. data/{test → compat}/app_test.rb +11 -10
  6. data/{test → compat}/application_test.rb +21 -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/base.rb +818 -0
  40. data/lib/sinatra/compat.rb +239 -0
  41. data/{images → lib/sinatra/images}/404.png +0 -0
  42. data/{images → lib/sinatra/images}/500.png +0 -0
  43. data/lib/sinatra/main.rb +48 -0
  44. data/lib/sinatra/test/bacon.rb +17 -0
  45. data/lib/sinatra/test/rspec.rb +7 -8
  46. data/lib/sinatra/test/spec.rb +3 -4
  47. data/lib/sinatra/test/unit.rb +3 -5
  48. data/lib/sinatra/test.rb +109 -0
  49. data/lib/sinatra.rb +4 -1466
  50. data/sinatra.gemspec +67 -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 +18 -5
  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 +9 -0
  64. data/test/result_test.rb +88 -0
  65. data/test/routing_test.rb +334 -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 +78 -46
  80. data/ChangeLog +0 -78
  81. data/lib/sinatra/test/methods.rb +0 -76
  82. data/test/event_context_test.rb +0 -15
@@ -0,0 +1,334 @@
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
+ fail unless params['foo'] == 'bar'
31
+ fail unless params[:foo] == 'bar'
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
+ fail unless params['foo'] == 'bar'
43
+ fail unless params['baz'] == 'biz'
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
+ fail unless 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
+ fail unless 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
+ fail unless params['foo'] == 'foo'
114
+ fail unless params['splat'] == ['bar/baz']
115
+ end
116
+ }
117
+
118
+ get '/foo/bar/baz'
119
+ assert ok?
120
+ end
121
+
122
+ it "supports paths that include spaces" do
123
+ mock_app {
124
+ get '/path with spaces' do
125
+ 'looks good'
126
+ end
127
+ }
128
+
129
+ get '/path%20with%20spaces'
130
+ assert ok?
131
+ assert_equal 'looks good', body
132
+ end
133
+
134
+ it "URL decodes named parameters and splats" do
135
+ mock_app {
136
+ get '/:foo/*' do
137
+ fail unless params['foo'] == 'hello world'
138
+ fail unless params['splat'] == ['how are you']
139
+ nil
140
+ end
141
+ }
142
+
143
+ get '/hello%20world/how%20are%20you'
144
+ assert ok?
145
+ end
146
+
147
+ it 'supports regular expressions' do
148
+ mock_app {
149
+ get(/^\/foo...\/bar$/) do
150
+ 'Hello World'
151
+ end
152
+ }
153
+
154
+ get '/foooom/bar'
155
+ assert ok?
156
+ assert_equal 'Hello World', body
157
+ end
158
+
159
+ it 'makes regular expression captures available in params[:captures]' do
160
+ mock_app {
161
+ get(/^\/fo(.*)\/ba(.*)/) do
162
+ fail unless params[:captures] == ['orooomma', 'f']
163
+ 'right on'
164
+ end
165
+ }
166
+
167
+ get '/foorooomma/baf'
168
+ assert ok?
169
+ assert_equal 'right on', body
170
+ end
171
+
172
+ it "returns response immediately on halt" do
173
+ mock_app {
174
+ get '/' do
175
+ halt 'Hello World'
176
+ 'Boo-hoo World'
177
+ end
178
+ }
179
+
180
+ get '/'
181
+ assert ok?
182
+ assert_equal 'Hello World', body
183
+ end
184
+
185
+ it "transitions to the next matching route on pass" do
186
+ mock_app {
187
+ get '/:foo' do
188
+ pass
189
+ 'Hello Foo'
190
+ end
191
+
192
+ get '/*' do
193
+ fail if params.include?('foo')
194
+ 'Hello World'
195
+ end
196
+ }
197
+
198
+ get '/bar'
199
+ assert ok?
200
+ assert_equal 'Hello World', body
201
+ end
202
+
203
+ it "transitions to 404 when passed and no subsequent route matches" do
204
+ mock_app {
205
+ get '/:foo' do
206
+ pass
207
+ 'Hello Foo'
208
+ end
209
+ }
210
+
211
+ get '/bar'
212
+ assert not_found?
213
+ end
214
+
215
+ it "passes when matching condition returns false" do
216
+ mock_app {
217
+ condition { params[:foo] == 'bar' }
218
+ get '/:foo' do
219
+ 'Hello World'
220
+ end
221
+ }
222
+
223
+ get '/bar'
224
+ assert ok?
225
+ assert_equal 'Hello World', body
226
+
227
+ get '/foo'
228
+ assert not_found?
229
+ end
230
+
231
+ it "does not pass when matching condition returns nil" do
232
+ mock_app {
233
+ condition { nil }
234
+ get '/:foo' do
235
+ 'Hello World'
236
+ end
237
+ }
238
+
239
+ get '/bar'
240
+ assert ok?
241
+ assert_equal 'Hello World', body
242
+ end
243
+
244
+ it "passes to next route when condition calls pass explicitly" do
245
+ mock_app {
246
+ condition { pass unless params[:foo] == 'bar' }
247
+ get '/:foo' do
248
+ 'Hello World'
249
+ end
250
+ }
251
+
252
+ get '/bar'
253
+ assert ok?
254
+ assert_equal 'Hello World', body
255
+
256
+ get '/foo'
257
+ assert not_found?
258
+ end
259
+
260
+ it "passes to the next route when host_name does not match" do
261
+ mock_app {
262
+ host_name 'example.com'
263
+ get '/foo' do
264
+ 'Hello World'
265
+ end
266
+ }
267
+ get '/foo'
268
+ assert not_found?
269
+
270
+ get '/foo', :env => { 'HTTP_HOST' => 'example.com' }
271
+ assert_equal 200, status
272
+ assert_equal 'Hello World', body
273
+ end
274
+
275
+ it "passes to the next route when user_agent does not match" do
276
+ mock_app {
277
+ user_agent(/Foo/)
278
+ get '/foo' do
279
+ 'Hello World'
280
+ end
281
+ }
282
+ get '/foo'
283
+ assert not_found?
284
+
285
+ get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
286
+ assert_equal 200, status
287
+ assert_equal 'Hello World', body
288
+ end
289
+
290
+ it "makes captures in user agent pattern available in params[:agent]" do
291
+ mock_app {
292
+ user_agent(/Foo (.*)/)
293
+ get '/foo' do
294
+ 'Hello ' + params[:agent].first
295
+ end
296
+ }
297
+ get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
298
+ assert_equal 200, status
299
+ assert_equal 'Hello Bar', body
300
+ end
301
+
302
+ it "filters by accept header" do
303
+ mock_app {
304
+ get '/', :provides => :xml do
305
+ request.env['HTTP_ACCEPT']
306
+ end
307
+ }
308
+
309
+ get '/', :env => { :accept => 'application/xml' }
310
+ assert ok?
311
+ assert_equal 'application/xml', body
312
+ assert_equal 'application/xml', response.headers['Content-Type']
313
+
314
+ get '/', :env => { :accept => 'text/html' }
315
+ assert !ok?
316
+ end
317
+
318
+ it "allows multiple mime types for accept header" do
319
+ types = ['image/jpeg', 'image/pjpeg']
320
+
321
+ mock_app {
322
+ get '/', :provides => types do
323
+ request.env['HTTP_ACCEPT']
324
+ end
325
+ }
326
+
327
+ types.each do |type|
328
+ get '/', :env => { :accept => type }
329
+ assert ok?
330
+ assert_equal type, body
331
+ assert_equal type, response.headers['Content-Type']
332
+ end
333
+ end
334
+ end
data/test/sass_test.rb CHANGED
@@ -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
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'Sinatra' do
4
+ it 'creates a new Sinatra::Base subclass on new' do
5
+ app =
6
+ Sinatra.new do
7
+ get '/' do
8
+ 'Hello World'
9
+ end
10
+ end
11
+ assert_same Sinatra::Base, app.superclass
12
+ end
13
+ end
@@ -0,0 +1,57 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'Static' do
4
+ F = ::File
5
+
6
+ before do
7
+ mock_app {
8
+ set :static, true
9
+ set :public, F.dirname(__FILE__)
10
+ }
11
+ end
12
+
13
+ it 'serves GET requests for files in the public directory' do
14
+ get "/#{F.basename(__FILE__)}"
15
+ assert ok?
16
+ assert_equal File.read(__FILE__), body
17
+ assert_equal File.size(__FILE__).to_s, response['Content-Length']
18
+ assert response.headers.include?('Last-Modified')
19
+ end
20
+
21
+ it 'serves HEAD requests for files in the public directory' do
22
+ head "/#{F.basename(__FILE__)}"
23
+ assert ok?
24
+ assert_equal '', body
25
+ assert_equal File.size(__FILE__).to_s, response['Content-Length']
26
+ assert response.headers.include?('Last-Modified')
27
+ end
28
+
29
+ it 'serves files in preference to custom routes' do
30
+ @app.get("/#{F.basename(__FILE__)}") { 'Hello World' }
31
+ get "/#{F.basename(__FILE__)}"
32
+ assert ok?
33
+ assert body != 'Hello World'
34
+ end
35
+
36
+ it 'does not serve directories' do
37
+ get "/"
38
+ assert not_found?
39
+ end
40
+
41
+ it 'passes to the next handler when the static option is disabled' do
42
+ @app.set :static, false
43
+ get "/#{F.basename(__FILE__)}"
44
+ assert not_found?
45
+ end
46
+
47
+ it 'passes to the next handler when the public option is nil' do
48
+ @app.set :public, nil
49
+ get "/#{F.basename(__FILE__)}"
50
+ assert not_found?
51
+ end
52
+
53
+ it '404s when a file is not found' do
54
+ get "/foobarbaz.txt"
55
+ assert not_found?
56
+ end
57
+ end