bmizerany-sinatra 0.8.10 → 0.9.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.
data/CHANGES CHANGED
@@ -1,42 +1,28 @@
1
1
  = 0.9.0 (unreleased)
2
2
 
3
- * Works with and requires Rack >= 0.9.1
4
-
5
- * Multiple Sinatra applications can now co-exist peacefully within a
6
- single process. The new "Sinatra::Base" class can be subclassed to
7
- establish a blank-slate Rack application or middleware component.
8
- Documentation on using these features is forth-coming; the following
9
- provides the basic gist: http://gist.github.com/38605
10
-
11
- * Parameters with subscripts are now parsed into a nested/recursive
12
- Hash structure. e.g., "post[title]=Hello&post[body]=World" yields
13
- params: {'post' => {'title' => 'Hello', 'body' => 'World'}}.
14
-
15
- * Regular expressions may now be used in route pattens; captures are
16
- available at "params[:captures]".
17
-
18
3
  * New ":provides" route condition takes an array of mime types and
19
4
  matches only when an Accept request header is present with a
20
5
  corresponding type. [cypher]
21
6
 
22
- * New request-level "pass" method; immediately exits the current block
23
- and passes control to the next matching route.
7
+ * Work with and require Rack >= 0.9
8
+
9
+ * Regular expressions may now be used in route pattens; captures are
10
+ available at "params[:captures]".
24
11
 
25
12
  * The request-level "body" method now takes a block; evaluation is
26
13
  deferred until an attempt is made to read the body. The block must
27
14
  return a String or Array.
28
15
 
29
- * New "route conditions" system for attaching rules for when a route
30
- matches. The :agent and :host route options now use this system.
31
-
32
- * New "dump_errors" option controls whether the backtrace is dumped to
33
- rack.errors when an exception is raised from a route. The option is
34
- enabled by default for top-level apps.
35
-
36
16
  * Better default "app_file", "root", "public", and "views" location
37
17
  detection; changes to "root" and "app_file" automatically cascade to
38
18
  other options that depend on them.
39
19
 
20
+ * New "route conditions" system for attaching rules for when a route
21
+ matches. The :agent and :host route options now use this system.
22
+
23
+ * New request-level "pass" method; immediately exits the current block
24
+ and passes control to the next matching route.
25
+
40
26
  * Error mappings are now split into two distinct layers: exception
41
27
  mappings and custom error pages. Exception mappings are registered
42
28
  with "error(Exception)" and are run only when the app raises an
@@ -45,16 +31,6 @@
45
31
  has the status code specified. It's also possible to register an error
46
32
  page for a range of status codes: "error(500..599)".
47
33
 
48
- * Sinatra's testing support is no longer dependent on Test::Unit. Requiring
49
- 'sinatra/test' adds the Sinatra::Test module and Sinatra::TestHarness
50
- class, which can be used with any test framework. The 'sinatra/test/unit',
51
- 'sinatra/test/spec', 'sinatra/test/rspec', or 'sinatra/test/bacon' files
52
- can be required to setup a framework-specific testing environment. See the
53
- README for more information.
54
-
55
- * Added support for Bacon (test framework). The 'sinatra/test/bacon' file
56
- can be required to setup Sinatra test helpers on Bacon::Context.
57
-
58
34
  * Deprecated "set_option" and "set_options"; use "set" instead.
59
35
 
60
36
  * Deprecated the "env" option ("options.env"); use "environment" instead.
@@ -79,10 +55,6 @@
79
55
  treated as internal server errors and result in a 500 response
80
56
  status.
81
57
 
82
- * Deprecated the "get_it", "post_it", "put_it", "delete_it", and "head_it"
83
- test helper methods. Use "get", "post", "put", "delete", and "head",
84
- respectively, instead.
85
-
86
58
  * Removed Event and EventContext classes. Applications are defined in a
87
59
  subclass of Sinatra::Base; each request is processed within an
88
60
  instance.
data/README.rdoc CHANGED
@@ -1,7 +1,9 @@
1
1
  = Sinatra
2
2
 
3
3
  Sinatra is a DSL for quickly creating web-applications in Ruby with minimal
4
- effort:
4
+ effort.
5
+
6
+ == Sample App
5
7
 
6
8
  # myapp.rb
7
9
  require 'rubygems'
@@ -30,6 +32,10 @@ Run with <tt>ruby myapp.rb</tt> and view at <tt>http://localhost:4567</tt>
30
32
  .. annihilate something ..
31
33
  end
32
34
 
35
+ head '/' do
36
+
37
+ end
38
+
33
39
  == Routes
34
40
 
35
41
  Routes are matched based on the order of declaration. The first route that
@@ -41,17 +47,14 @@ Basic routes:
41
47
  ...
42
48
  end
43
49
 
44
- Route patterns may include named parameters, accessible via the
45
- <tt>params</tt> hash:
50
+ Named parameters:
46
51
 
47
52
  get '/:name' do
48
53
  # matches "GET /foo" and "GET /bar"
49
54
  # params[:name] is 'foo' or 'bar'
50
- "Hello #{params[:name]}!"
51
55
  end
52
56
 
53
- Route patterns may also include splat (or wildcard) parameters, accessible
54
- via the <tt>params[:splat]</tt> array.
57
+ Splat parameters:
55
58
 
56
59
  get '/say/*/to/*' do
57
60
  # matches /say/hello/to/world
@@ -63,13 +66,7 @@ via the <tt>params[:splat]</tt> array.
63
66
  params[:splat] # => ["path/to/file", "xml"]
64
67
  end
65
68
 
66
- Route matching with Regular Expressions:
67
-
68
- get %r{/hello/([\w]+)} do
69
- "Hello, #{params[:captures].first}!"
70
- end
71
-
72
- Routes may include a variety of matching conditions, such as the user agent:
69
+ User agent matching:
73
70
 
74
71
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
75
72
  "You're using Songbird version #{params[:agent][0]}"
@@ -81,29 +78,33 @@ Routes may include a variety of matching conditions, such as the user agent:
81
78
 
82
79
  == Static Files
83
80
 
84
- Static files are served from the <tt>./public</tt> directory. You can specify
85
- a different location by setting the <tt>:public</tt> option:
81
+ Put all of your static content in the ./public directory
82
+
83
+ root
84
+ \ public
85
+
86
+ To use a different static directory:
86
87
 
87
88
  set :public, File.dirname(__FILE__) + '/static'
88
89
 
89
- == Views / Templates
90
+ == Views
91
+
92
+ Views are searched for in a ./views directory in the same location as
93
+ your main application.
90
94
 
91
- Templates are assumed to be located directly under a <tt>./views</tt>
92
- directory. To use a different views directory:
95
+ To use a different views directory:
93
96
 
94
97
  set :views, File.dirname(__FILE__) + '/templates'
95
98
 
96
99
  === Haml Templates
97
100
 
98
- The haml gem/library is required to render HAML templates:
99
-
100
101
  get '/' do
101
102
  haml :index
102
103
  end
103
104
 
104
105
  Renders <tt>./views/index.haml</tt>.
105
106
 
106
- === Erb Templates
107
+ === Erb
107
108
 
108
109
  get '/' do
109
110
  erb :index
@@ -111,20 +112,11 @@ Renders <tt>./views/index.haml</tt>.
111
112
 
112
113
  Renders <tt>./views/index.erb</tt>
113
114
 
114
- === Builder Templates
115
+ === Builder
115
116
 
116
- The builder gem/library is required to render builder templates:
117
+ See Sinatra::Builder
117
118
 
118
- get '/' do
119
- content_type 'application/xml', :charset => 'utf-8'
120
- builder :index
121
- end
122
-
123
- Renders <tt>./views/index.builder</tt>.
124
-
125
- === Sass Templates
126
-
127
- The sass gem/library is required to render Sass templates:
119
+ === Sass
128
120
 
129
121
  get '/stylesheet.css' do
130
122
  content_type 'text/css', :charset => 'utf-8'
@@ -143,8 +135,9 @@ Renders the inlined template string.
143
135
 
144
136
  === Accessing Variables
145
137
 
146
- Templates are evaluated within the same context as the route blocks. Instance
147
- variables set in route blocks are available in templates:
138
+ Templates are evaluated within the Sinatra::EventContext instance
139
+ used to evaluate event blocks. Instance variables set in event
140
+ blocks can be accessed direcly in views:
148
141
 
149
142
  get '/:id' do
150
143
  @foo = Foo.find(params[:id])
@@ -165,32 +158,27 @@ other templates.
165
158
 
166
159
  Templates may be defined at the end of the source file:
167
160
 
168
- require 'rubygems'
169
- require 'sinatra'
170
-
171
161
  get '/' do
172
162
  haml :index
173
163
  end
174
164
 
165
+ use_in_file_templates!
166
+
175
167
  __END__
176
168
 
177
169
  @@ layout
178
- %html
179
- = yield
170
+ X
171
+ = yield
172
+ X
180
173
 
181
174
  @@ index
182
175
  %div.title Hello world!!!!!
183
176
 
184
- NOTE: Sinatra will automaticly load any in-file-templates in the
185
- source file that first required sinatra. If you have in-file-templates
186
- in another source file you will need to explicitly call
187
- +use_in_file_templates! on main in that file.
188
-
189
177
  It's also possible to define named templates using the top-level template
190
178
  method:
191
179
 
192
180
  template :layout do
193
- "%html\n =yield\n"
181
+ "X\n=yield\nX"
194
182
  end
195
183
 
196
184
  template :index do
@@ -201,17 +189,9 @@ method:
201
189
  haml :index
202
190
  end
203
191
 
204
- If a template named "layout" exists, it will be used each time a template
205
- is rendered. You can disable layouts by passing <tt>:layout => false</tt>.
206
-
207
- get '/' do
208
- haml :index, :layout => !request.xhr?
209
- end
210
-
211
192
  == Helpers
212
193
 
213
- Use the top-level <tt>helpers</tt> method to define helper methods for use in
214
- route blocks and templates:
194
+ The top-level <tt>helpers</tt> method
215
195
 
216
196
  helpers do
217
197
  def bar(name)
@@ -225,9 +205,7 @@ route blocks and templates:
225
205
 
226
206
  == Filters
227
207
 
228
- Before filters are evaluated before each request within the context of the
229
- request and can modify the request and response. Instance variables set in
230
- filters are accessible by routes and templates.
208
+ Before filters are evaluated in request context before routing is performed:
231
209
 
232
210
  before do
233
211
  @note = 'Hi!'
@@ -239,75 +217,64 @@ filters are accessible by routes and templates.
239
217
  params[:splat] #=> 'bar/baz'
240
218
  end
241
219
 
242
- == Halting
220
+ Before filters can modify the request and response; instance variables are
221
+ available to routes.
243
222
 
244
- To immediately stop a request during a before filter or route use:
223
+ == Halt!
245
224
 
246
- halt
225
+ To immediately stop a request during a before filter or event use:
247
226
 
248
- You can also specify a body when halting ...
227
+ throw :halt
249
228
 
250
- halt 'this will be the body'
229
+ Set the body to a simple string
251
230
 
252
- Set the status and body ...
231
+ throw :halt, 'this will be the body'
253
232
 
254
- halt 401, 'go away!'
233
+ Set status then the body
255
234
 
256
- == Passing
235
+ throw :halt, [401, 'go away!']
257
236
 
258
- A route can punt processing to the next matching route using the <tt>pass</tt>
259
- statement:
237
+ Run a proc inside the Sinatra::EventContext instance and set the body to the
238
+ result
260
239
 
261
- get '/guess/:who' do
262
- pass unless params[:who] == 'Frank'
263
- "You got me!"
264
- end
265
-
266
- get '/guess/*' do
267
- "You missed!"
268
- end
269
-
270
- The route block is immediately exited and control continues with the next
271
- matching route. If no matching route is found, a 404 is returned.
240
+ throw :halt, lambda { puts 'In a proc!'; 'I just wrote to $stdout!' }
272
241
 
273
242
  == Configuration and Reloading
274
243
 
275
244
  Sinatra supports multiple environments and reloading. Reloading happens
276
- before each request when running under the <tt>:development</tt>
277
- environment. Wrap your configurations (e.g., database connections, constants,
278
- etc.) in <tt>configure</tt> blocks to protect them from reloading or to
279
- target specific environments.
245
+ before every request when running under the :development environment. Wrap
246
+ your configurations in <tt>configure</tt> (i.e. Database connections, Constants,
247
+ etc.) to protect them from reloading or to target specific environments.
280
248
 
281
- Run once, at startup, in any environment:
249
+ All environments:
282
250
 
283
251
  configure do
284
252
  ...
285
253
  end
286
254
 
287
- Run only when the environment (RACK_ENV environment variable) is set to
288
- <tt>:production</tt>.
255
+ Production:
289
256
 
290
257
  configure :production do
291
258
  ...
292
259
  end
293
260
 
294
- Run when the environment (RACK_ENV environment variable) is set to
295
- either <tt>:production</tt> or <tt>:test</tt>.
261
+ Two at a time:
296
262
 
297
263
  configure :production, :test do
298
264
  ...
299
265
  end
300
266
 
267
+ This is also really nifty for error handling.
268
+
301
269
  == Error handling
302
270
 
303
- Error handlers run within the same context as routes and before filters, which
304
- means you get all the goodies it has to offer, like <tt>haml</tt>, <tt>erb</tt>,
305
- <tt>halt</tt>, etc.
271
+ Error handlers run inside the current Sinatra::EventContext instance, which
272
+ means you get all the goodies it has to offer (i.e. haml, erb, throw :halt,
273
+ etc.)
306
274
 
307
275
  === Not Found
308
276
 
309
- When a <tt>Sinatra::NotFound</tt> exception is raised, or the response's status
310
- code is 404, the <tt>not_found</tt> handler is invoked:
277
+ When Sinatra::NotFound is raised, the not_found handler is invoked:
311
278
 
312
279
  not_found do
313
280
  'This is nowhere to be found'
@@ -315,12 +282,14 @@ code is 404, the <tt>not_found</tt> handler is invoked:
315
282
 
316
283
  === Error
317
284
 
318
- The +error+ handler is invoked any time an exception is raised from a route
319
- block or before filter. The exception object can be obtained from the
320
- 'sinatra.error' Rack variable:
285
+ By default, the +error+ handler is invoked on Sinatra::ServerError or when
286
+ an unknown error occurs.
287
+
288
+ The exception can be obtained from the 'sinatra.error' variable in
289
+ request.env.
321
290
 
322
291
  error do
323
- 'Sorry there was a nasty error - ' + env['sinatra.error'].name
292
+ 'Sorry there was a nasty error - ' + request.env['sinatra.error'].name
324
293
  end
325
294
 
326
295
  Custom errors:
@@ -340,12 +309,12 @@ You get this:
340
309
  So what happened was... something bad
341
310
 
342
311
  Sinatra installs special not_found and error handlers when running under
343
- the development environment.
312
+ the development.
344
313
 
345
314
  == Mime types
346
315
 
347
- When using <tt>send_file</tt> or static files you may have mime types Sinatra
348
- doesn't understand. Use +mime+ to register them by file extension:
316
+ When using send_file or static files you may have mime types Sinatra doesn't
317
+ understand. Use +mime+ in those cases.
349
318
 
350
319
  mime :foo, 'text/foo'
351
320
 
@@ -386,61 +355,59 @@ typically don't have to +use+ them explicitly.
386
355
 
387
356
  == Testing
388
357
 
389
- The Sinatra::Test module includes a variety of helper methods for testing
390
- your Sinatra app. Sinatra includes support for Test::Unit, test-spec, RSpec,
391
- and Bacon through separate source files.
392
-
393
- === Test::Unit
358
+ === Test/Unit
394
359
 
360
+ require 'rubygems'
395
361
  require 'sinatra'
396
362
  require 'sinatra/test/unit'
397
363
  require 'my_sinatra_app'
398
364
 
399
365
  class MyAppTest < Test::Unit::TestCase
366
+
400
367
  def test_my_default
401
- get '/'
368
+ get_it '/'
402
369
  assert_equal 'My Default Page!', @response.body
403
370
  end
404
371
 
405
372
  def test_with_agent
406
- get '/', :agent => 'Songbird'
373
+ get_it '/', :agent => 'Songbird'
407
374
  assert_equal 'You're in Songbird!', @response.body
408
375
  end
409
376
 
410
377
  ...
411
- end
412
378
 
413
- === Test::Spec
379
+ end
414
380
 
415
- Install the test-spec gem and require <tt>'sinatra/test/spec'</tt> before
416
- your app:
381
+ === Test/Spec
417
382
 
383
+ require 'rubygems'
418
384
  require 'sinatra'
419
385
  require 'sinatra/test/spec'
420
386
  require 'my_sinatra_app'
421
387
 
422
388
  describe 'My app' do
389
+
423
390
  it "should show a default page" do
424
- get '/'
391
+ get_it '/'
425
392
  should.be.ok
426
393
  body.should.equal 'My Default Page!'
427
394
  end
428
395
 
429
396
  ...
397
+
430
398
  end
431
399
 
432
400
  === RSpec
433
401
 
434
- Install the rspec gem and require <tt>'sinatra/test/rspec'</tt> before
435
- your app:
436
-
402
+ require 'rubygems'
403
+ require 'spec'
437
404
  require 'sinatra'
438
405
  require 'sinatra/test/rspec'
439
406
  require 'my_sinatra_app'
440
407
 
441
408
  describe 'My app' do
442
409
  it 'should show a default page' do
443
- get '/'
410
+ get_it '/'
444
411
  @response.should be_ok
445
412
  @response.body.should == 'My Default Page!'
446
413
  end
@@ -449,35 +416,20 @@ your app:
449
416
 
450
417
  end
451
418
 
452
- === Bacon
453
-
454
- require 'sinatra'
455
- require 'sinatra/test/bacon'
456
- require 'my_sinatra_app'
457
-
458
- describe 'My app' do
459
- it 'should be ok' do
460
- get '/'
461
- should.be.ok
462
- body.should == 'Im OK'
463
- end
464
- end
465
-
466
- See Sinatra::Test for more information on +get+, +post+, +put+, and
467
- friends.
419
+ See Sinatra::Test::Methods for more information on +get_it+, +post_it+,
420
+ +put_it+, and friends.
468
421
 
469
422
  == Command line
470
423
 
471
424
  Sinatra applications can be run directly:
472
425
 
473
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-s HANDLER]
426
+ ruby myapp.rb [-h] [-x] [-p PORT] [-e ENVIRONMENT]
474
427
 
475
428
  Options are:
476
429
 
477
430
  -h # help
478
431
  -p # set the port (default is 4567)
479
432
  -e # set the environment (default is development)
480
- -s # specify rack server/handler (default is thin)
481
433
  -x # turn on the mutex lock (default is off)
482
434
 
483
435
  == Contributing
@@ -510,7 +462,7 @@ screencasts about Git, which you can find here: http://www.gitcasts.com/
510
462
 
511
463
  at the top of your sinatra_app.rb file:
512
464
 
513
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
465
+ $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
514
466
  require 'sinatra'
515
467
 
516
468
  get '/about' do
@@ -1,6 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  context "Simple Events" do
4
+
4
5
  def simple_request_hash(method, path)
5
6
  Rack::Request.new({
6
7
  'REQUEST_METHOD' => method.to_s.upcase,
@@ -13,16 +14,16 @@ context "Simple Events" do
13
14
 
14
15
  def invoke_simple(path, request_path, &b)
15
16
  params = nil
16
- get path do
17
- params = self.params
18
- b.call if b
19
- end
17
+ mock_app {
18
+ get path do
19
+ params = self.params
20
+ b.call if b
21
+ end
22
+ }
20
23
  get_it request_path
21
24
  MockResult.new(b, params)
22
25
  end
23
26
 
24
- setup { Sinatra.application = nil }
25
-
26
27
  specify "return last value" do
27
28
  block = Proc.new { 'Simple' }
28
29
  result = invoke_simple('/', '/', &block)
@@ -37,7 +38,6 @@ context "Simple Events" do
37
38
  result.params.should.equal "foo" => 'a', "bar" => 'b'
38
39
 
39
40
  # unscapes
40
- Sinatra.application = nil
41
41
  result = invoke_simple('/:foo/:bar', '/a/blake%20mizerany')
42
42
  result.should.not.be.nil
43
43
  result.params.should.equal "foo" => 'a', "bar" => 'blake mizerany'
@@ -48,17 +48,14 @@ context "Simple Events" do
48
48
  result.should.not.be.nil
49
49
  result.params.should.equal "foo" => 'a', "bar" => 'b'
50
50
 
51
- Sinatra.application = nil
52
51
  result = invoke_simple('/?:foo?/?:bar?', '/a/')
53
52
  result.should.not.be.nil
54
53
  result.params.should.equal "foo" => 'a', "bar" => nil
55
54
 
56
- Sinatra.application = nil
57
55
  result = invoke_simple('/?:foo?/?:bar?', '/a')
58
56
  result.should.not.be.nil
59
57
  result.params.should.equal "foo" => 'a', "bar" => nil
60
58
 
61
- Sinatra.application = nil
62
59
  result = invoke_simple('/:foo?/?:bar?', '/')
63
60
  result.should.not.be.nil
64
61
  result.params.should.equal "foo" => nil, "bar" => nil
data/compat/helper.rb CHANGED
@@ -1,9 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'mocha'
3
3
 
4
- # disable warnings in compat specs.
5
- $VERBOSE = nil
6
-
7
4
  $:.unshift File.dirname(File.dirname(__FILE__)) + "/lib"
8
5
 
9
6
  ENV['RACK_ENV'] ||= 'test'
@@ -13,18 +10,9 @@ require 'sinatra/test'
13
10
  require 'sinatra/test/unit'
14
11
  require 'sinatra/test/spec'
15
12
 
16
- module Sinatra::Test
17
- # we need to remove the new test helper methods since they conflict with
18
- # the top-level methods of the same name.
19
- %w(get head post put delete).each do |verb|
20
- remove_method verb
21
- end
22
- include Sinatra::Delegator
23
- end
24
-
25
13
  class Test::Unit::TestCase
26
- include Sinatra::Test
27
14
  def setup
28
15
  @app = lambda { |env| Sinatra::Application.call(env) }
29
16
  end
17
+ include Sinatra::Test
30
18
  end