darkhelmet-sinatra 0.9.1.1 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/AUTHORS +2 -0
  2. data/CHANGES +180 -0
  3. data/LICENSE +1 -1
  4. data/README.jp.rdoc +552 -0
  5. data/README.rdoc +177 -38
  6. data/Rakefile +18 -25
  7. data/lib/sinatra.rb +1 -2
  8. data/lib/sinatra/base.rb +405 -305
  9. data/lib/sinatra/main.rb +5 -24
  10. data/lib/sinatra/showexceptions.rb +303 -0
  11. data/lib/sinatra/tilt.rb +509 -0
  12. data/sinatra.gemspec +21 -51
  13. data/test/base_test.rb +123 -93
  14. data/test/builder_test.rb +2 -1
  15. data/test/contest.rb +64 -0
  16. data/test/erb_test.rb +1 -1
  17. data/test/erubis_test.rb +82 -0
  18. data/test/extensions_test.rb +24 -8
  19. data/test/filter_test.rb +99 -3
  20. data/test/haml_test.rb +25 -3
  21. data/test/helper.rb +43 -48
  22. data/test/helpers_test.rb +500 -424
  23. data/test/mapped_error_test.rb +163 -137
  24. data/test/middleware_test.rb +3 -3
  25. data/test/request_test.rb +16 -1
  26. data/test/response_test.rb +2 -2
  27. data/test/result_test.rb +1 -1
  28. data/test/route_added_hook_test.rb +59 -0
  29. data/test/routing_test.rb +170 -22
  30. data/test/sass_test.rb +44 -1
  31. data/test/server_test.rb +19 -13
  32. data/test/sinatra_test.rb +1 -1
  33. data/test/static_test.rb +9 -2
  34. data/test/templates_test.rb +78 -11
  35. data/test/views/error.builder +3 -0
  36. data/test/views/error.erb +3 -0
  37. data/test/views/error.erubis +3 -0
  38. data/test/views/error.haml +3 -0
  39. data/test/views/error.sass +2 -0
  40. data/test/views/foo/hello.test +1 -0
  41. data/test/views/hello.erubis +1 -0
  42. data/test/views/layout2.erubis +2 -0
  43. metadata +37 -55
  44. data/compat/app_test.rb +0 -282
  45. data/compat/application_test.rb +0 -262
  46. data/compat/builder_test.rb +0 -101
  47. data/compat/compat_test.rb +0 -12
  48. data/compat/custom_error_test.rb +0 -62
  49. data/compat/erb_test.rb +0 -136
  50. data/compat/events_test.rb +0 -78
  51. data/compat/filter_test.rb +0 -30
  52. data/compat/haml_test.rb +0 -233
  53. data/compat/helper.rb +0 -30
  54. data/compat/mapped_error_test.rb +0 -72
  55. data/compat/pipeline_test.rb +0 -45
  56. data/compat/public/foo.xml +0 -1
  57. data/compat/sass_test.rb +0 -57
  58. data/compat/sessions_test.rb +0 -42
  59. data/compat/streaming_test.rb +0 -133
  60. data/compat/sym_params_test.rb +0 -19
  61. data/compat/template_test.rb +0 -30
  62. data/compat/use_in_file_templates_test.rb +0 -47
  63. data/compat/views/foo.builder +0 -1
  64. data/compat/views/foo.erb +0 -1
  65. data/compat/views/foo.haml +0 -1
  66. data/compat/views/foo.sass +0 -2
  67. data/compat/views/foo_layout.erb +0 -2
  68. data/compat/views/foo_layout.haml +0 -2
  69. data/compat/views/layout_test/foo.builder +0 -1
  70. data/compat/views/layout_test/foo.erb +0 -1
  71. data/compat/views/layout_test/foo.haml +0 -1
  72. data/compat/views/layout_test/foo.sass +0 -2
  73. data/compat/views/layout_test/layout.builder +0 -3
  74. data/compat/views/layout_test/layout.erb +0 -1
  75. data/compat/views/layout_test/layout.haml +0 -1
  76. data/compat/views/layout_test/layout.sass +0 -2
  77. data/compat/views/no_layout/no_layout.builder +0 -1
  78. data/compat/views/no_layout/no_layout.haml +0 -1
  79. data/lib/sinatra/compat.rb +0 -250
  80. data/lib/sinatra/test.rb +0 -126
  81. data/lib/sinatra/test/bacon.rb +0 -19
  82. data/lib/sinatra/test/rspec.rb +0 -13
  83. data/lib/sinatra/test/spec.rb +0 -11
  84. data/lib/sinatra/test/unit.rb +0 -13
  85. data/test/data/reload_app_file.rb +0 -3
  86. data/test/options_test.rb +0 -374
  87. data/test/reload_test.rb +0 -68
  88. data/test/test_test.rb +0 -144
@@ -1,6 +1,6 @@
1
1
  = Sinatra
2
2
 
3
- Sinatra is a DSL for quickly creating web-applications in Ruby with minimal
3
+ Sinatra is a DSL for quickly creating web applications in Ruby with minimal
4
4
  effort:
5
5
 
6
6
  # myapp.rb
@@ -45,7 +45,7 @@ Route patterns may include named parameters, accessible via the
45
45
  <tt>params</tt> hash:
46
46
 
47
47
  get '/hello/:name' do
48
- # matches "GET /foo" and "GET /bar"
48
+ # matches "GET /hello/foo" and "GET /hello/bar"
49
49
  # params[:name] is 'foo' or 'bar'
50
50
  "Hello #{params[:name]}!"
51
51
  end
@@ -109,28 +109,67 @@ directory. To use a different views directory:
109
109
 
110
110
  set :views, File.dirname(__FILE__) + '/templates'
111
111
 
112
+ One important thing to remember is that you always have to reference
113
+ templates with symbols, even if they're in a subdirectory (in this
114
+ case use <tt>:'subdir/template'</tt>). Rendering methods will render
115
+ any strings passed to them directly.
116
+
112
117
  === Haml Templates
113
118
 
114
119
  The haml gem/library is required to render HAML templates:
115
120
 
121
+ ## You'll need to require haml in your app
122
+ require 'haml'
123
+
116
124
  get '/' do
117
125
  haml :index
118
126
  end
119
127
 
120
128
  Renders <tt>./views/index.haml</tt>.
121
129
 
130
+ {Haml's options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html]
131
+ can be set globally through Sinatra's configurations,
132
+ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
133
+ and overridden on an individual basis.
134
+
135
+ set :haml, {:format => :html5 } # default Haml format is :xhtml
136
+
137
+ get '/' do
138
+ haml :index, :haml_options => {:format => :html4 } # overridden
139
+ end
140
+
141
+
122
142
  === Erb Templates
123
143
 
144
+ ## You'll need to require erb in your app
145
+ require 'erb'
146
+
124
147
  get '/' do
125
148
  erb :index
126
149
  end
127
150
 
128
151
  Renders <tt>./views/index.erb</tt>
129
152
 
153
+ === Erubis
154
+
155
+ The erubis gem/library is required to render builder templates:
156
+
157
+ ## You'll need to require erubis in your app
158
+ require 'erubis'
159
+
160
+ get '/' do
161
+ erubis :index
162
+ end
163
+
164
+ Renders <tt>./views/index.erubis</tt>
165
+
130
166
  === Builder Templates
131
167
 
132
168
  The builder gem/library is required to render builder templates:
133
169
 
170
+ ## You'll need to require builder in your app
171
+ require 'builder'
172
+
134
173
  get '/' do
135
174
  content_type 'application/xml', :charset => 'utf-8'
136
175
  builder :index
@@ -142,6 +181,9 @@ Renders <tt>./views/index.builder</tt>.
142
181
 
143
182
  The sass gem/library is required to render Sass templates:
144
183
 
184
+ ## You'll need to require haml or sass in your app
185
+ require 'sass'
186
+
145
187
  get '/stylesheet.css' do
146
188
  content_type 'text/css', :charset => 'utf-8'
147
189
  sass :stylesheet
@@ -149,6 +191,18 @@ The sass gem/library is required to render Sass templates:
149
191
 
150
192
  Renders <tt>./views/stylesheet.sass</tt>.
151
193
 
194
+ {Sass' options}[http://haml.hamptoncatlin.com/docs/rdoc/classes/Sass.html]
195
+ can be set globally through Sinatra's configurations,
196
+ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
197
+ and overridden on an individual basis.
198
+
199
+ set :sass, {:style => :compact } # default Sass style is :nested
200
+
201
+ get '/stylesheet.css' do
202
+ content_type 'text/css', :charset => 'utf-8'
203
+ sass :stylesheet, :style => :expanded # overridden
204
+ end
205
+
152
206
  === Inline Templates
153
207
 
154
208
  get '/' do
@@ -177,7 +231,7 @@ Or, specify an explicit Hash of local variables:
177
231
  This is typically used when rendering templates as partials from within
178
232
  other templates.
179
233
 
180
- === In-file Templates
234
+ === Inline Templates
181
235
 
182
236
  Templates may be defined at the end of the source file:
183
237
 
@@ -197,9 +251,9 @@ Templates may be defined at the end of the source file:
197
251
  @@ index
198
252
  %div.title Hello world!!!!!
199
253
 
200
- NOTE: In-file templates defined in the source file that requires sinatra
201
- are automatically loaded. Call the <tt>use_in_file_templates!</tt>
202
- method explicitly if you have in-file templates in other source files.
254
+ NOTE: Inline templates defined in the source file that requires sinatra
255
+ are automatically loaded. Call `enable :inline_templates` explicitly if you
256
+ have inline templates in other source files.
203
257
 
204
258
  === Named Templates
205
259
 
@@ -255,43 +309,53 @@ filters are accessible by routes and templates:
255
309
  params[:splat] #=> 'bar/baz'
256
310
  end
257
311
 
312
+ After filter are evaluated after each request within the context of the
313
+ request and can also modify the request and response. Instance variables
314
+ set in before filters and routes are accessible by after filters:
315
+
316
+ after do
317
+ puts response.status
318
+ end
319
+
258
320
  == Halting
259
321
 
260
- To immediately stop a request during a before filter or route use:
322
+ To immediately stop a request within a filter or route use:
261
323
 
262
324
  halt
263
325
 
264
- You can also specify a body when halting ...
326
+ You can also specify the status when halting ...
327
+
328
+ halt 410
329
+
330
+ Or the body ...
265
331
 
266
332
  halt 'this will be the body'
267
333
 
268
- Or set the status and body ...
334
+ Or both ...
269
335
 
270
336
  halt 401, 'go away!'
271
337
 
338
+ With headers ...
339
+
340
+ halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
341
+
272
342
  == Passing
273
343
 
274
344
  A route can punt processing to the next matching route using <tt>pass</tt>:
275
345
 
276
346
  get '/guess/:who' do
277
347
  pass unless params[:who] == 'Frank'
278
- "You got me!"
348
+ 'You got me!'
279
349
  end
280
350
 
281
351
  get '/guess/*' do
282
- "You missed!"
352
+ 'You missed!'
283
353
  end
284
354
 
285
355
  The route block is immediately exited and control continues with the next
286
356
  matching route. If no matching route is found, a 404 is returned.
287
357
 
288
- == Configuration and Reloading
289
-
290
- Sinatra supports multiple environments and reloading. Reloading happens
291
- before each request when running under the <tt>:development</tt>
292
- environment. Wrap your configurations (e.g., database connections, constants,
293
- etc.) in <tt>configure</tt> blocks to protect them from reloading or to
294
- target specific environments.
358
+ == Configuration
295
359
 
296
360
  Run once, at startup, in any environment:
297
361
 
@@ -300,14 +364,14 @@ Run once, at startup, in any environment:
300
364
  end
301
365
 
302
366
  Run only when the environment (RACK_ENV environment variable) is set to
303
- <tt>:production</tt>.
367
+ <tt>:production</tt>:
304
368
 
305
369
  configure :production do
306
370
  ...
307
371
  end
308
372
 
309
- Run when the environment (RACK_ENV environment variable) is set to
310
- either <tt>:production</tt> or <tt>:test</tt>.
373
+ Run when the environment is set to either <tt>:production</tt> or
374
+ <tt>:test</tt>:
311
375
 
312
376
  configure :production, :test do
313
377
  ...
@@ -331,7 +395,7 @@ code is 404, the <tt>not_found</tt> handler is invoked:
331
395
  === Error
332
396
 
333
397
  The +error+ handler is invoked any time an exception is raised from a route
334
- block or before filter. The exception object can be obtained from the
398
+ block or a filter. The exception object can be obtained from the
335
399
  <tt>sinatra.error</tt> Rack variable:
336
400
 
337
401
  error do
@@ -354,15 +418,35 @@ You get this:
354
418
 
355
419
  So what happened was... something bad
356
420
 
421
+ Alternatively, you can install error handler for a status code:
422
+
423
+ error 403 do
424
+ 'Access forbidden'
425
+ end
426
+
427
+ get '/secret' do
428
+ 403
429
+ end
430
+
431
+ Or a range:
432
+
433
+ error 400..510 do
434
+ 'Boom'
435
+ end
436
+
357
437
  Sinatra installs special <tt>not_found</tt> and <tt>error</tt> handlers when
358
438
  running under the development environment.
359
439
 
360
440
  == Mime types
361
441
 
362
442
  When using <tt>send_file</tt> or static files you may have mime types Sinatra
363
- doesn't understand. Use +mime+ to register them by file extension:
443
+ doesn't understand. Use +mime_type+ to register them by file extension:
364
444
 
365
- mime :foo, 'text/foo'
445
+ mime_type :foo, 'text/foo'
446
+
447
+ You can also use it with the +content_type+ helper:
448
+
449
+ content_type :foo
366
450
 
367
451
  == Rack Middleware
368
452
 
@@ -401,45 +485,100 @@ typically don't have to +use+ them explicitly.
401
485
 
402
486
  == Testing
403
487
 
404
- The Sinatra::Test mixin and Sinatra::TestHarness class include a variety of
405
- helper methods for testing your Sinatra app:
488
+ Sinatra tests can be written using any Rack-based testing library
489
+ or framework. {Rack::Test}[http://gitrdoc.com/brynary/rack-test] is
490
+ recommended:
406
491
 
407
492
  require 'my_sinatra_app'
408
- require 'test/unit'
409
- require 'sinatra/test'
493
+ require 'rack/test'
410
494
 
411
495
  class MyAppTest < Test::Unit::TestCase
412
- include Sinatra::Test
496
+ include Rack::Test::Methods
497
+
498
+ def app
499
+ Sinatra::Application
500
+ end
413
501
 
414
502
  def test_my_default
415
503
  get '/'
416
- assert_equal 'Hello World!', @response.body
504
+ assert_equal 'Hello World!', last_response.body
417
505
  end
418
506
 
419
507
  def test_with_params
420
- get '/meet', {:name => 'Frank'}
421
- assert_equal 'Hello Frank!', @response.body
508
+ get '/meet', :name => 'Frank'
509
+ assert_equal 'Hello Frank!', last_response.body
422
510
  end
423
511
 
424
512
  def test_with_rack_env
425
- get '/', {}, :agent => 'Songbird'
426
- assert_equal "You're using Songbird!", @response.body
513
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
514
+ assert_equal "You're using Songbird!", last_response.body
515
+ end
516
+ end
517
+
518
+ NOTE: The built-in Sinatra::Test module and Sinatra::TestHarness class
519
+ are deprecated as of the 0.9.2 release.
520
+
521
+ == Sinatra::Base - Middleware, Libraries, and Modular Apps
522
+
523
+ Defining your app at the top-level works well for micro-apps but has
524
+ considerable drawbacks when building reuseable components such as Rack
525
+ middleware, Rails metal, simple libraries with a server component, or
526
+ even Sinatra extensions. The top-level DSL pollutes the Object namespace
527
+ and assumes a micro-app style configuration (e.g., a single application
528
+ file, ./public and ./views directories, logging, exception detail page,
529
+ etc.). That's where Sinatra::Base comes into play:
530
+
531
+ require 'sinatra/base'
532
+
533
+ class MyApp < Sinatra::Base
534
+ set :sessions, true
535
+ set :foo, 'bar'
536
+
537
+ get '/' do
538
+ 'Hello world!'
427
539
  end
428
540
  end
429
541
 
430
- See http://www.sinatrarb.com/testing.html for more on Sinatra::Test and using it
431
- with other test frameworks such as RSpec, Bacon, and test/spec.
542
+ The MyApp class is an independent Rack component that can act as
543
+ Rack middleware, a Rack application, or Rails metal. You can +use+ or
544
+ +run+ this class from a rackup +config.ru+ file; or, control a server
545
+ component shipped as a library:
546
+
547
+ MyApp.run! :host => 'localhost', :port => 9090
548
+
549
+ The methods available to Sinatra::Base subclasses are exactly as those
550
+ available via the top-level DSL. Most top-level apps can be converted to
551
+ Sinatra::Base components with two modifications:
552
+
553
+ * Your file should require +sinatra/base+ instead of +sinatra+;
554
+ otherwise, all of Sinatra's DSL methods are imported into the main
555
+ namespace.
556
+ * Put your app's routes, error handlers, filters, and options in a subclass
557
+ of Sinatra::Base.
558
+
559
+ +Sinatra::Base+ is a blank slate. Most options are disabled by default,
560
+ including the built-in server. See {Options and Configuration}[http://sinatra.github.com/configuration.html]
561
+ for details on available options and their behavior.
562
+
563
+ SIDEBAR: Sinatra's top-level DSL is implemented using a simple delegation
564
+ system. The +Sinatra::Application+ class -- a special subclass of
565
+ Sinatra::Base -- receives all :get, :put, :post, :delete, :before,
566
+ :error, :not_found, :configure, and :set messages sent to the
567
+ top-level. Have a look at the code for yourself: here's the
568
+ {Sinatra::Delegator mixin}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1064]
569
+ being {included into the main namespace}[http://github.com/sinatra/sinatra/blob/master/lib/sinatra/main.rb#L25].
432
570
 
433
571
  == Command line
434
572
 
435
573
  Sinatra applications can be run directly:
436
574
 
437
- ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-s HANDLER]
575
+ ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-h HOST] [-s HANDLER]
438
576
 
439
577
  Options are:
440
578
 
441
579
  -h # help
442
580
  -p # set the port (default is 4567)
581
+ -h # set the host (default is 0.0.0.0)
443
582
  -e # set the environment (default is development)
444
583
  -s # specify rack server/handler (default is thin)
445
584
  -x # turn on the mutex lock (default is off)
@@ -454,7 +593,7 @@ clone and run your app with the <tt>sinatra/lib</tt> directory on the
454
593
  git clone git://github.com/sinatra/sinatra.git
455
594
  ruby -Isinatra/lib myapp.rb
456
595
 
457
- Alternatively, you can add the <tt>sinatra/lib<tt> directory to the
596
+ Alternatively, you can add the <tt>sinatra/lib</tt> directory to the
458
597
  <tt>LOAD_PATH</tt> in your application:
459
598
 
460
599
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rake/clean'
2
2
  require 'rake/testtask'
3
3
  require 'fileutils'
4
4
 
5
- task :default => [:test]
5
+ task :default => :test
6
6
  task :spec => :test
7
7
 
8
8
  # SPECS ===============================================================
@@ -12,12 +12,6 @@ Rake::TestTask.new(:test) do |t|
12
12
  t.ruby_opts = ['-rubygems'] if defined? Gem
13
13
  end
14
14
 
15
- desc 'Run compatibility specs (requires test/spec)'
16
- task :compat do |t|
17
- pattern = ENV['TEST'] || '.*'
18
- sh "specrb --testcase '#{pattern}' -Ilib:test compat/*_test.rb"
19
- end
20
-
21
15
  # PACKAGING ============================================================
22
16
 
23
17
  # Load the gemspec using the same limitations as github
@@ -33,7 +27,7 @@ def spec
33
27
  end
34
28
 
35
29
  def package(ext='')
36
- "dist/sinatra-#{spec.version}" + ext
30
+ "pkg/sinatra-#{spec.version}" + ext
37
31
  end
38
32
 
39
33
  desc 'Build packages'
@@ -44,15 +38,15 @@ task :install => package('.gem') do
44
38
  sh "gem install #{package('.gem')}"
45
39
  end
46
40
 
47
- directory 'dist/'
48
- CLOBBER.include('dist')
41
+ directory 'pkg/'
42
+ CLOBBER.include('pkg')
49
43
 
50
- file package('.gem') => %w[dist/ sinatra.gemspec] + spec.files do |f|
44
+ file package('.gem') => %w[pkg/ sinatra.gemspec] + spec.files do |f|
51
45
  sh "gem build sinatra.gemspec"
52
46
  mv File.basename(f.name), f.name
53
47
  end
54
48
 
55
- file package('.tar.gz') => %w[dist/] + spec.files do |f|
49
+ file package('.tar.gz') => %w[pkg/] + spec.files do |f|
56
50
  sh <<-SH
57
51
  git archive \
58
52
  --prefix=sinatra-#{source_version}/ \
@@ -64,7 +58,7 @@ end
64
58
  # Rubyforge Release / Publish Tasks ==================================
65
59
 
66
60
  desc 'Publish gem and tarball to rubyforge'
67
- task 'publish:gem' => [package('.gem'), package('.tar.gz')] do |t|
61
+ task 'release' => [package('.gem'), package('.tar.gz')] do |t|
68
62
  sh <<-end
69
63
  rubyforge add_release sinatra sinatra #{spec.version} #{package('.gem')} &&
70
64
  rubyforge add_file sinatra sinatra #{spec.version} #{package('.tar.gz')}
@@ -95,12 +89,6 @@ file 'doc/api/index.html' => FileList['lib/**/*.rb','README.rdoc'] do |f|
95
89
  end
96
90
  CLEAN.include 'doc/api'
97
91
 
98
- def rdoc_to_html(file_name)
99
- require 'rdoc/markup/to_html'
100
- rdoc = RDoc::Markup::ToHtml.new
101
- rdoc.convert(File.read(file_name))
102
- end
103
-
104
92
  # Gemspec Helpers ====================================================
105
93
 
106
94
  def source_version
@@ -108,12 +96,7 @@ def source_version
108
96
  line.match(/.*VERSION = '(.*)'/)[1]
109
97
  end
110
98
 
111
- project_files =
112
- FileList[
113
- '{lib,test,compat,images}/**',
114
- 'Rakefile', 'CHANGES', 'README.rdoc'
115
- ]
116
- file 'sinatra.gemspec' => project_files do |f|
99
+ task 'sinatra.gemspec' => FileList['{lib,test,compat}/**','Rakefile','CHANGES','*.rdoc'] do |f|
117
100
  # read spec file and split out manifest section
118
101
  spec = File.read(f.name)
119
102
  head, manifest, tail = spec.split(" # = MANIFEST =\n")
@@ -134,3 +117,13 @@ file 'sinatra.gemspec' => project_files do |f|
134
117
  File.open(f.name, 'w') { |io| io.write(spec) }
135
118
  puts "updated #{f.name}"
136
119
  end
120
+
121
+ # Rcov ==============================================================
122
+ namespace :test do
123
+ desc 'Mesures test coverage'
124
+ task :coverage do
125
+ rm_f "coverage"
126
+ rcov = "rcov --text-summary --test-unit-only -Ilib"
127
+ system("#{rcov} --no-html --no-color test/*_test.rb")
128
+ end
129
+ end