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
data/AUTHORS ADDED
@@ -0,0 +1,40 @@
1
+ Sinatra was designed and developed by Blake Mizerany (bmizerany) in
2
+ California. Continued development would not be possible without the ongoing
3
+ financial support provided by Heroku <heroku.com> and the emotional support
4
+ provided by Adam Wiggins (adamwiggins), Chris Wanstrath (defunkt), PJ Hyett (pjhyett), and
5
+ the rest of the Github crew.
6
+
7
+ Special thanks to the following extraordinary individuals, who-out which
8
+ Sinatra would not be possible:
9
+
10
+ * Ryan Tomayko (rtomayko) for constantly fixing whitespace errors 60d5006
11
+ * Ezra Zygmuntowicz (ezmobius) for initial help and letting Blake steal
12
+ some of merbs internal code.
13
+ * Christopher Schneid (cschneid) for The Book, the blog (gittr.com),
14
+ irclogger.com, and a bunch of useful patches.
15
+ * Markus Prinz (cypher) for patches over the years, caring about
16
+ the README, and hanging in there when times were rough.
17
+ * Simon Rozet (sr) for a ton of doc patches, HAML options, and all that
18
+ advocacy stuff he's going to do for 1.0.
19
+ * Erik Kastner (kastner) for fixing MIME_TYPES under Rack 0.5.
20
+ * Ben Bleything (bleything) for caring about HTTP status codes and doc fixes.
21
+ * Igal Koshevoy (igal) for root path detection under Thin/Passenger.
22
+ * Jon Crosby (jcrosby) for coffee breaks, doc fixes, and just because, man.
23
+ * Karel Minarik (karmi) for screaming until the website came back up.
24
+ * Jeremy Evans (jeremyevans) for unbreaking optional path params (twice!)
25
+ * The GitHub guys for stealing Blake's table.
26
+ * Nickolas Means (nmeans) for Sass template support.
27
+ * Victor Hugo Borja (vic) for splat'n routes specs and doco.
28
+ * Avdi Grimm (avdi) for basic RSpec support.
29
+ * Jack Danger Canty for a more accurate root directory and for making me
30
+ watch this just now: http://www.youtube.com/watch?v=ueaHLHgskkw.
31
+ * Mathew Walker for making escaped paths work with static files.
32
+ * Millions of Us for having the problem that led to Sinatra's conception.
33
+ * Songbird for the problems that helped Sinatra's future become realized.
34
+ * Rick Olsen (technoweenie) for the killer plug at RailsConf '08.
35
+ * Steven Garcia for the amazing custom artwork you see on 404's and 500's
36
+
37
+ and last but not least:
38
+
39
+ * Frank Sinatra (chairman of the board) for having so much class he
40
+ deserves a web-framework named after him.
data/CHANGES ADDED
@@ -0,0 +1,189 @@
1
+ = 0.9.0 / 2009-01-18
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
+ * New ":provides" route condition takes an array of mime types and
19
+ matches only when an Accept request header is present with a
20
+ corresponding type. [cypher]
21
+
22
+ * New request-level "pass" method; immediately exits the current block
23
+ and passes control to the next matching route.
24
+
25
+ * The request-level "body" method now takes a block; evaluation is
26
+ deferred until an attempt is made to read the body. The block must
27
+ return a String or Array.
28
+
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
+ * Better default "app_file", "root", "public", and "views" location
37
+ detection; changes to "root" and "app_file" automatically cascade to
38
+ other options that depend on them.
39
+
40
+ * Error mappings are now split into two distinct layers: exception
41
+ mappings and custom error pages. Exception mappings are registered
42
+ with "error(Exception)" and are run only when the app raises an
43
+ exception. Custom error pages are registered with "error(status_code)",
44
+ where "status_code" is an integer, and are run any time the response
45
+ has the status code specified. It's also possible to register an error
46
+ page for a range of status codes: "error(500..599)".
47
+
48
+ * In-file templates are now automatically imported from the file that
49
+ requires 'sinatra'. The use_in_file_templates! method is still available
50
+ for loading templates from other files.
51
+
52
+ * Sinatra's testing support is no longer dependent on Test::Unit. Requiring
53
+ 'sinatra/test' adds the Sinatra::Test module and Sinatra::TestHarness
54
+ class, which can be used with any test framework. The 'sinatra/test/unit',
55
+ 'sinatra/test/spec', 'sinatra/test/rspec', or 'sinatra/test/bacon' files
56
+ can be required to setup a framework-specific testing environment. See the
57
+ README for more information.
58
+
59
+ * Added support for Bacon (test framework). The 'sinatra/test/bacon' file
60
+ can be required to setup Sinatra test helpers on Bacon::Context.
61
+
62
+ * Deprecated "set_option" and "set_options"; use "set" instead.
63
+
64
+ * Deprecated the "env" option ("options.env"); use "environment" instead.
65
+
66
+ * Deprecated the request level "stop" method; use "halt" instead.
67
+
68
+ * Deprecated the request level "entity_tag" method; use "etag" instead.
69
+ Both "entity_tag" and "etag" were previously supported.
70
+
71
+ * Deprecated the request level "headers" method (HTTP response headers);
72
+ use "response['Header-Name']" instead.
73
+
74
+ * Deprecated "Sinatra.application"; use "Sinatra::Application" instead.
75
+
76
+ * Deprecated setting Sinatra.application = nil to reset an application.
77
+ This should no longer be necessary.
78
+
79
+ * Deprecated "Sinatra.default_options"; use
80
+ "Sinatra::Default.set(key, value)" instead.
81
+
82
+ * Deprecated the "ServerError" exception. All Exceptions are now
83
+ treated as internal server errors and result in a 500 response
84
+ status.
85
+
86
+ * Deprecated the "get_it", "post_it", "put_it", "delete_it", and "head_it"
87
+ test helper methods. Use "get", "post", "put", "delete", and "head",
88
+ respectively, instead.
89
+
90
+ * Removed Event and EventContext classes. Applications are defined in a
91
+ subclass of Sinatra::Base; each request is processed within an
92
+ instance.
93
+
94
+ = 0.3.3 / 2009-01-06
95
+
96
+ * Pin to Rack 0.4.0 (this is the last release on Rack 0.4)
97
+
98
+ * Log unhandled exception backtraces to rack.errors.
99
+
100
+ * Use RACK_ENV environment variable to establish Sinatra
101
+ environment when given. Thin sets this when started with
102
+ the -e argument.
103
+
104
+ * BUG: raising Sinatra::NotFound resulted in a 500 response
105
+ code instead of 404.
106
+
107
+ * BUG: use_in_file_templates! fails with CR/LF (#45)
108
+
109
+ * BUG: Sinatra detects the app file and root path when run under
110
+ thin/passenger.
111
+
112
+ = 0.3.2
113
+
114
+ * BUG: Static and send_file read entire file into String before
115
+ sending. Updated to stream with 8K chunks instead.
116
+
117
+ * Rake tasks and assets for building basic documentation website.
118
+ See http://sinatra.rubyforge.org
119
+
120
+ * Various minor doc fixes.
121
+
122
+ = 0.3.1
123
+
124
+ * Unbreak optional path parameters [jeremyevans]
125
+
126
+ = 0.3.0
127
+
128
+ * Add sinatra.gemspec w/ support for github gem builds. Forks can now
129
+ enable the build gem option in github to get free username-sinatra.gem
130
+ builds: gem install username-sinatra.gem --source=http://gems.github.com/
131
+
132
+ * Require rack-0.4 gem; removes frozen rack dir.
133
+
134
+ * Basic RSpec support; require 'sinatra/test/rspec' instead of
135
+ 'sinatra/test/spec' to use. [avdi]
136
+
137
+ * before filters can modify request environment vars used for
138
+ routing (e.g., PATH_INFO, REQUEST_METHOD, etc.) for URL rewriting
139
+ type functionality.
140
+
141
+ * In-file templates now uses @@ instead of ## as template separator.
142
+
143
+ * Top-level environment test predicates: development?, test?, production?
144
+
145
+ * Top-level "set", "enable", and "disable" methods for tweaking
146
+ app options. [rtomayko]
147
+
148
+ * Top-level "use" method for building Rack middleware pipelines
149
+ leading to app. See README for usage. [rtomayko]
150
+
151
+ * New "reload" option - set false to disable reloading in development.
152
+
153
+ * New "host" option - host/ip to bind to [cschneid]
154
+
155
+ * New "app_file" option - override the file to reload in development
156
+ mode [cschneid]
157
+
158
+ * Development error/not_found page cleanup [sr, adamwiggins]
159
+
160
+ * Remove a bunch of core extensions (String#to_param, String#from_param,
161
+ Hash#from_params, Hash#to_params, Hash#symbolize_keys, Hash#pass)
162
+
163
+ * Various grammar and formatting fixes to README; additions on
164
+ community and contributing [cypher]
165
+
166
+ * Build RDoc using Hanna template: http://sinatrarb.rubyforge.org/api
167
+
168
+ * Specs, documentation and fixes for splat'n routes [vic]
169
+
170
+ * Fix whitespace errors across all source files. [rtomayko]
171
+
172
+ * Fix streaming issues with Mongrel (body not closed). [bmizerany]
173
+
174
+ * Fix various issues with environment not being set properly (configure
175
+ blocks not running, error pages not registering, etc.) [cypher]
176
+
177
+ * Fix to allow locals to be passed to ERB templates [cschneid]
178
+
179
+ * Fix locking issues causing random errors during reload in development.
180
+
181
+ * Fix for escaped paths not resolving static files [Matthew Walker]
182
+
183
+ = 0.2.1
184
+
185
+ * File upload fix and minor tweaks.
186
+
187
+ = 0.2.0
188
+
189
+ * Initial gem release of 0.2 codebase.
@@ -1,9 +1,7 @@
1
1
  = Sinatra
2
2
 
3
3
  Sinatra is a DSL for quickly creating web-applications in Ruby with minimal
4
- effort.
5
-
6
- == Sample App
4
+ effort:
7
5
 
8
6
  # myapp.rb
9
7
  require 'rubygems'
@@ -32,78 +30,80 @@ Run with <tt>ruby myapp.rb</tt> and view at <tt>http://localhost:4567</tt>
32
30
  .. annihilate something ..
33
31
  end
34
32
 
35
- head '/' do
36
-
37
- end
38
-
39
- NOTE: <tt>put</tt> and <tt>delete</tt> are also triggered when a
40
- <tt>_method</tt> parameter is set to PUT or DELETE and the HTTP request method
41
- is POST
42
-
43
33
  == Routes
44
34
 
45
35
  Routes are matched based on the order of declaration. The first route that
46
36
  matches the request is invoked.
47
37
 
48
- Simple:
38
+ Basic routes:
49
39
 
50
40
  get '/hi' do
51
41
  ...
52
42
  end
53
43
 
54
- Named parameters:
44
+ Route patterns may include named parameters, accessible via the
45
+ <tt>params</tt> hash:
55
46
 
56
47
  get '/:name' do
57
- # matches /sinatra and the like and sets params[:name]
48
+ # matches "GET /foo" and "GET /bar"
49
+ # params[:name] is 'foo' or 'bar'
50
+ "Hello #{params[:name]}!"
58
51
  end
59
52
 
60
- Splat parameters:
53
+ Route patterns may also include splat (or wildcard) parameters, accessible
54
+ via the <tt>params[:splat]</tt> array.
61
55
 
62
56
  get '/say/*/to/*' do
63
57
  # matches /say/hello/to/world
64
- params["splat"] # => ["hello", "world"]
58
+ params[:splat] # => ["hello", "world"]
65
59
  end
66
60
 
67
61
  get '/download/*.*' do
68
62
  # matches /download/path/to/file.xml
69
- params["splat"] # => ["path/to/file", "xml"]
63
+ params[:splat] # => ["path/to/file", "xml"]
64
+ end
65
+
66
+ Route matching with Regular Expressions:
67
+
68
+ get %r{/hello/([\w]+)} do
69
+ "Hello, #{params[:captures].first}!"
70
70
  end
71
71
 
72
- User agent matching:
72
+ Routes may include a variety of matching conditions, such as the user agent:
73
73
 
74
74
  get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
75
75
  "You're using Songbird version #{params[:agent][0]}"
76
76
  end
77
77
 
78
78
  get '/foo' do
79
- # matches non-songbird browsers
79
+ # Matches non-songbird browsers
80
80
  end
81
81
 
82
- == Static files
82
+ == Static Files
83
83
 
84
- Put all of your static content in the ./public directory
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:
85
86
 
86
- root
87
- \ public
87
+ set :public, File.dirname(__FILE__) + '/static'
88
88
 
89
- If a file exists that maps to the REQUEST_PATH then it is served and the
90
- request ends. Otherwise, Sinatra will look for an event that matches the
91
- path.
89
+ == Views / Templates
92
90
 
93
- == Views
91
+ Templates are assumed to be located directly under a <tt>./views</tt>
92
+ directory. To use a different views directory:
94
93
 
95
- Views are searched for in a "views" directory in the same location as
96
- your main application.
94
+ set :views, File.dirname(__FILE__) + '/templates'
97
95
 
98
96
  === Haml Templates
99
97
 
98
+ The haml gem/library is required to render HAML templates:
99
+
100
100
  get '/' do
101
101
  haml :index
102
102
  end
103
103
 
104
104
  Renders <tt>./views/index.haml</tt>.
105
105
 
106
- === Erb
106
+ === Erb Templates
107
107
 
108
108
  get '/' do
109
109
  erb :index
@@ -111,11 +111,20 @@ Renders <tt>./views/index.haml</tt>.
111
111
 
112
112
  Renders <tt>./views/index.erb</tt>
113
113
 
114
- === Builder
114
+ === Builder Templates
115
+
116
+ The builder gem/library is required to render builder templates:
117
+
118
+ get '/' do
119
+ content_type 'application/xml', :charset => 'utf-8'
120
+ builder :index
121
+ end
122
+
123
+ Renders <tt>./views/index.builder</tt>.
115
124
 
116
- See Sinatra::Builder
125
+ === Sass Templates
117
126
 
118
- === Sass
127
+ The sass gem/library is required to render Sass templates:
119
128
 
120
129
  get '/stylesheet.css' do
121
130
  content_type 'text/css', :charset => 'utf-8'
@@ -134,9 +143,8 @@ Renders the inlined template string.
134
143
 
135
144
  === Accessing Variables
136
145
 
137
- Templates are evaluated within the Sinatra::EventContext instance
138
- used to evaluate event blocks. Instance variables set in event
139
- blocks can be accessed direcly in views:
146
+ Templates are evaluated within the same context as the route blocks. Instance
147
+ variables set in route blocks are available in templates:
140
148
 
141
149
  get '/:id' do
142
150
  @foo = Foo.find(params[:id])
@@ -157,27 +165,32 @@ other templates.
157
165
 
158
166
  Templates may be defined at the end of the source file:
159
167
 
168
+ require 'rubygems'
169
+ require 'sinatra'
170
+
160
171
  get '/' do
161
172
  haml :index
162
173
  end
163
174
 
164
- use_in_file_templates!
165
-
166
175
  __END__
167
176
 
168
177
  @@ layout
169
- X
170
- = yield
171
- X
178
+ %html
179
+ = yield
172
180
 
173
181
  @@ index
174
182
  %div.title Hello world!!!!!
175
183
 
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
+
176
189
  It's also possible to define named templates using the top-level template
177
190
  method:
178
191
 
179
192
  template :layout do
180
- "X\n=yield\nX"
193
+ "%html\n =yield\n"
181
194
  end
182
195
 
183
196
  template :index do
@@ -188,10 +201,17 @@ method:
188
201
  haml :index
189
202
  end
190
203
 
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
+
191
211
  == Helpers
192
212
 
193
- The top-level <tt>helpers</tt> method takes a block and extends all
194
- EventContext instances with the methods defined:
213
+ Use the top-level <tt>helpers</tt> method to define helper methods for use in
214
+ route blocks and templates:
195
215
 
196
216
  helpers do
197
217
  def bar(name)
@@ -205,95 +225,89 @@ EventContext instances with the methods defined:
205
225
 
206
226
  == Filters
207
227
 
208
- These are run in Sinatra::EventContext before every event.
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.
209
231
 
210
232
  before do
211
- .. this code will run before each event ..
233
+ @note = 'Hi!'
234
+ request.path_info = '/foo/bar/baz'
212
235
  end
213
236
 
214
- == Halt!
215
-
216
- To immediately stop a request during a before filter or event use:
217
-
218
- throw :halt
219
-
220
- Set the body to the result of a helper method
221
-
222
- throw :halt, :helper_method
223
-
224
- Set the body to the result of a helper method after sending it parameters from
225
- the local scope
226
-
227
- throw :halt, [:helper_method, foo, bar]
237
+ get '/foo/*' do
238
+ @note #=> 'Hi!'
239
+ params[:splat] #=> 'bar/baz'
240
+ end
228
241
 
229
- Set the body to a simple string
242
+ == Halting
230
243
 
231
- throw :halt, 'this will be the body'
244
+ To immediately stop a request during a before filter or route use:
232
245
 
233
- Set status then the body
246
+ halt
234
247
 
235
- throw :halt, [401, 'go away!']
248
+ You can also specify a body when halting ...
236
249
 
237
- Set the status then call a helper method with params from local scope
250
+ halt 'this will be the body'
238
251
 
239
- throw :halt, [401, [:helper_method, foo, bar]]
252
+ Set the status and body ...
240
253
 
241
- Run a proc inside the Sinatra::EventContext instance and set the body to the
242
- result
254
+ halt 401, 'go away!'
243
255
 
244
- throw :halt, lambda { puts 'In a proc!'; 'I just wrote to $stdout!' }
256
+ == Passing
245
257
 
246
- Create you own to_result
258
+ A route can punt processing to the next matching route using the <tt>pass</tt>
259
+ statement:
247
260
 
248
- class MyResultObject
249
- def to_result(event_context, *args)
250
- event_context.body = 'This will be the body!
251
- end
261
+ get '/guess/:who' do
262
+ pass unless params[:who] == 'Frank'
263
+ "You got me!"
252
264
  end
253
265
 
254
- get '/' do
255
- throw :halt, MyResultObject.new
266
+ get '/guess/*' do
267
+ "You missed!"
256
268
  end
257
269
 
258
- Get the gist? If you want more fun with this then checkout <tt>to_result</tt>
259
- on Array, Symbol, Fixnum, NilClass.
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.
260
272
 
261
273
  == Configuration and Reloading
262
274
 
263
275
  Sinatra supports multiple environments and reloading. Reloading happens
264
- before every request when running under the :development environment. Wrap
265
- your configurations in <tt>configure</tt> (i.e. Database connections, Constants,
266
- etc.) to protect them from reloading or to target specific environments.
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.
267
280
 
268
- All environments:
281
+ Run once, at startup, in any environment:
269
282
 
270
283
  configure do
271
284
  ...
272
285
  end
273
286
 
274
- Production:
287
+ Run only when the environment (RACK_ENV environment variable) is set to
288
+ <tt>:production</tt>.
275
289
 
276
290
  configure :production do
277
291
  ...
278
292
  end
279
293
 
280
- Two at a time:
294
+ Run when the environment (RACK_ENV environment variable) is set to
295
+ either <tt>:production</tt> or <tt>:test</tt>.
281
296
 
282
297
  configure :production, :test do
283
298
  ...
284
299
  end
285
300
 
286
- This is also really nifty for error handling.
287
-
288
301
  == Error handling
289
302
 
290
- Error handlers run inside the current Sinatra::EventContext instance, which
291
- means you get all the goodies it has to offer (i.e. haml, erb, throw :halt,
292
- etc.)
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.
293
306
 
294
307
  === Not Found
295
308
 
296
- When Sinatra::NotFound is raised, the not_found handler is invoked:
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:
297
311
 
298
312
  not_found do
299
313
  'This is nowhere to be found'
@@ -301,14 +315,12 @@ When Sinatra::NotFound is raised, the not_found handler is invoked:
301
315
 
302
316
  === Error
303
317
 
304
- By default, the +error+ handler is invoked on Sinatra::ServerError or when
305
- an unknown error occurs.
306
-
307
- The exception can be obtained from the 'sinatra.error' variable in
308
- request.env.
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:
309
321
 
310
322
  error do
311
- 'Sorry there was a nasty error - ' + request.env['sinatra.error'].name
323
+ 'Sorry there was a nasty error - ' + env['sinatra.error'].name
312
324
  end
313
325
 
314
326
  Custom errors:
@@ -328,12 +340,12 @@ You get this:
328
340
  So what happened was... something bad
329
341
 
330
342
  Sinatra installs special not_found and error handlers when running under
331
- the development.
343
+ the development environment.
332
344
 
333
345
  == Mime types
334
346
 
335
- When using send_file or static files you may have mime types Sinatra doesn't
336
- understand. Use +mime+ in those cases.
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:
337
349
 
338
350
  mime :foo, 'text/foo'
339
351
 
@@ -374,59 +386,61 @@ typically don't have to +use+ them explicitly.
374
386
 
375
387
  == Testing
376
388
 
377
- === Test/Unit
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
378
394
 
379
- require 'rubygems'
380
395
  require 'sinatra'
381
396
  require 'sinatra/test/unit'
382
397
  require 'my_sinatra_app'
383
398
 
384
399
  class MyAppTest < Test::Unit::TestCase
385
-
386
400
  def test_my_default
387
- get_it '/'
401
+ get '/'
388
402
  assert_equal 'My Default Page!', @response.body
389
403
  end
390
404
 
391
405
  def test_with_agent
392
- get_it '/', :agent => 'Songbird'
406
+ get '/', :agent => 'Songbird'
393
407
  assert_equal 'You're in Songbird!', @response.body
394
408
  end
395
409
 
396
410
  ...
397
-
398
411
  end
399
412
 
400
- === Test/Spec
413
+ === Test::Spec
414
+
415
+ Install the test-spec gem and require <tt>'sinatra/test/spec'</tt> before
416
+ your app:
401
417
 
402
- require 'rubygems'
403
418
  require 'sinatra'
404
419
  require 'sinatra/test/spec'
405
420
  require 'my_sinatra_app'
406
421
 
407
422
  describe 'My app' do
408
-
409
423
  it "should show a default page" do
410
- get_it '/'
424
+ get '/'
411
425
  should.be.ok
412
426
  body.should.equal 'My Default Page!'
413
427
  end
414
428
 
415
429
  ...
416
-
417
430
  end
418
431
 
419
432
  === RSpec
420
433
 
421
- require 'rubygems'
422
- require 'spec'
434
+ Install the rspec gem and require <tt>'sinatra/test/rspec'</tt> before
435
+ your app:
436
+
423
437
  require 'sinatra'
424
438
  require 'sinatra/test/rspec'
425
439
  require 'my_sinatra_app'
426
440
 
427
441
  describe 'My app' do
428
442
  it 'should show a default page' do
429
- get_it '/'
443
+ get '/'
430
444
  @response.should be_ok
431
445
  @response.body.should == 'My Default Page!'
432
446
  end
@@ -435,20 +449,35 @@ typically don't have to +use+ them explicitly.
435
449
 
436
450
  end
437
451
 
438
- See Sinatra::Test::Methods for more information on +get_it+, +post_it+,
439
- +put_it+, and friends.
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.
440
468
 
441
469
  == Command line
442
470
 
443
471
  Sinatra applications can be run directly:
444
472
 
445
- ruby myapp.rb [-h] [-x] [-p PORT] [-e ENVIRONMENT]
473
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-s HANDLER]
446
474
 
447
475
  Options are:
448
476
 
449
477
  -h # help
450
478
  -p # set the port (default is 4567)
451
479
  -e # set the environment (default is development)
480
+ -s # specify rack server/handler (default is thin)
452
481
  -x # turn on the mutex lock (default is off)
453
482
 
454
483
  == Contributing
@@ -481,7 +510,7 @@ screencasts about Git, which you can find here: http://www.gitcasts.com/
481
510
 
482
511
  at the top of your sinatra_app.rb file:
483
512
 
484
- $:.unshift File.dirname(__FILE__) + '/sinatra/lib'
513
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
485
514
  require 'sinatra'
486
515
 
487
516
  get '/about' do