sinatra 0.9.6 → 1.0.a

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 (67) hide show
  1. data/CHANGES +83 -29
  2. data/README.jp.rdoc +552 -0
  3. data/README.rdoc +31 -9
  4. data/Rakefile +73 -91
  5. data/lib/sinatra.rb +0 -1
  6. data/lib/sinatra/base.rb +248 -269
  7. data/lib/sinatra/main.rb +3 -11
  8. data/lib/sinatra/tilt.rb +509 -0
  9. data/sinatra.gemspec +15 -49
  10. data/test/erubis_test.rb +82 -0
  11. data/test/extensions_test.rb +1 -1
  12. data/test/filter_test.rb +125 -3
  13. data/test/helpers_test.rb +59 -2
  14. data/test/mapped_error_test.rb +31 -0
  15. data/test/middleware_test.rb +1 -1
  16. data/test/request_test.rb +15 -0
  17. data/test/routing_test.rb +76 -0
  18. data/test/{options_test.rb → settings_test.rb} +46 -50
  19. data/test/static_test.rb +13 -0
  20. data/test/templates_test.rb +43 -10
  21. data/test/views/error.erubis +3 -0
  22. data/test/views/hello.erubis +1 -0
  23. data/test/views/layout2.erubis +2 -0
  24. metadata +61 -88
  25. data/compat/app_test.rb +0 -282
  26. data/compat/application_test.rb +0 -262
  27. data/compat/builder_test.rb +0 -101
  28. data/compat/compat_test.rb +0 -12
  29. data/compat/custom_error_test.rb +0 -62
  30. data/compat/erb_test.rb +0 -136
  31. data/compat/events_test.rb +0 -78
  32. data/compat/filter_test.rb +0 -30
  33. data/compat/haml_test.rb +0 -237
  34. data/compat/helper.rb +0 -34
  35. data/compat/mapped_error_test.rb +0 -72
  36. data/compat/pipeline_test.rb +0 -45
  37. data/compat/public/foo.xml +0 -1
  38. data/compat/sass_test.rb +0 -67
  39. data/compat/sessions_test.rb +0 -42
  40. data/compat/streaming_test.rb +0 -133
  41. data/compat/sym_params_test.rb +0 -18
  42. data/compat/template_test.rb +0 -30
  43. data/compat/use_in_file_templates_test.rb +0 -47
  44. data/compat/views/foo.builder +0 -1
  45. data/compat/views/foo.erb +0 -1
  46. data/compat/views/foo.haml +0 -1
  47. data/compat/views/foo.sass +0 -2
  48. data/compat/views/foo_layout.erb +0 -2
  49. data/compat/views/foo_layout.haml +0 -2
  50. data/compat/views/layout_test/foo.builder +0 -1
  51. data/compat/views/layout_test/foo.erb +0 -1
  52. data/compat/views/layout_test/foo.haml +0 -1
  53. data/compat/views/layout_test/foo.sass +0 -2
  54. data/compat/views/layout_test/layout.builder +0 -3
  55. data/compat/views/layout_test/layout.erb +0 -1
  56. data/compat/views/layout_test/layout.haml +0 -1
  57. data/compat/views/layout_test/layout.sass +0 -2
  58. data/compat/views/no_layout/no_layout.builder +0 -1
  59. data/compat/views/no_layout/no_layout.haml +0 -1
  60. data/lib/sinatra/compat.rb +0 -258
  61. data/lib/sinatra/test.rb +0 -129
  62. data/lib/sinatra/test/bacon.rb +0 -19
  63. data/lib/sinatra/test/rspec.rb +0 -13
  64. data/lib/sinatra/test/spec.rb +0 -11
  65. data/lib/sinatra/test/unit.rb +0 -13
  66. data/test/render_backtrace_test.rb +0 -145
  67. data/test/test_test.rb +0 -155
@@ -101,6 +101,37 @@ class MappedErrorTest < Test::Unit::TestCase
101
101
  assert_equal 404, status
102
102
  assert_equal "Lost, are we?", body
103
103
  end
104
+
105
+ it 'inherits error mappings from base class' do
106
+ base = Class.new(Sinatra::Base)
107
+ base.error(FooError) { 'base class' }
108
+
109
+ mock_app(base) {
110
+ set :raise_errors, false
111
+ get '/' do
112
+ raise FooError
113
+ end
114
+ }
115
+
116
+ get '/'
117
+ assert_equal 'base class', body
118
+ end
119
+
120
+ it 'overrides error mappings in base class' do
121
+ base = Class.new(Sinatra::Base)
122
+ base.error(FooError) { 'base class' }
123
+
124
+ mock_app(base) {
125
+ set :raise_errors, false
126
+ error(FooError) { 'subclass' }
127
+ get '/' do
128
+ raise FooError
129
+ end
130
+ }
131
+
132
+ get '/'
133
+ assert_equal 'subclass', body
134
+ end
104
135
  end
105
136
 
106
137
  describe 'Custom Error Pages' do
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  class MiddlewareTest < Test::Unit::TestCase
4
4
  setup do
5
- @app = mock_app(Sinatra::Base) {
5
+ @app = mock_app(Sinatra::Application) {
6
6
  get '/*' do
7
7
  response.headers['X-Tests'] = env['test.ran'].
8
8
  map { |n| n.split('::').last }.
@@ -15,4 +15,19 @@ class RequestTest < Test::Unit::TestCase
15
15
  )
16
16
  assert_equal 'bar', request.params['foo']
17
17
  end
18
+
19
+ it 'is secure when the url scheme is https' do
20
+ request = Sinatra::Request.new('rack.url_scheme' => 'https')
21
+ assert request.secure?
22
+ end
23
+
24
+ it 'is not secure when the url scheme is http' do
25
+ request = Sinatra::Request.new('rack.url_scheme' => 'http')
26
+ assert !request.secure?
27
+ end
28
+
29
+ it 'respects X-Forwarded-Proto header for proxied SSL' do
30
+ request = Sinatra::Request.new('HTTP_X_FORWARDED_PROTO' => 'https')
31
+ assert request.secure?
32
+ end
18
33
  end
@@ -60,6 +60,15 @@ class RoutingTest < Test::Unit::TestCase
60
60
  assert_equal 404, status
61
61
  end
62
62
 
63
+ it "404s and sets X-Cascade header when no route satisfies the request" do
64
+ mock_app {
65
+ get('/foo') { }
66
+ }
67
+ get '/bar'
68
+ assert_equal 404, status
69
+ assert_equal 'pass', response.headers['X-Cascade']
70
+ end
71
+
63
72
  it "overrides the content-type in error handlers" do
64
73
  mock_app {
65
74
  before { content_type 'text/plain' }
@@ -462,6 +471,38 @@ class RoutingTest < Test::Unit::TestCase
462
471
  assert not_found?
463
472
  end
464
473
 
474
+ it "transitions to 404 and sets X-Cascade header when passed and no subsequent route matches" do
475
+ mock_app {
476
+ get '/:foo' do
477
+ pass
478
+ 'Hello Foo'
479
+ end
480
+
481
+ get '/bar' do
482
+ 'Hello Bar'
483
+ end
484
+ }
485
+
486
+ get '/foo'
487
+ assert not_found?
488
+ assert_equal 'pass', response.headers['X-Cascade']
489
+ end
490
+
491
+ it "uses optional block passed to pass as route block if no other route is found" do
492
+ mock_app {
493
+ get "/" do
494
+ pass do
495
+ "this"
496
+ end
497
+ "not this"
498
+ end
499
+ }
500
+
501
+ get "/"
502
+ assert ok?
503
+ assert "this", body
504
+ end
505
+
465
506
  it "passes when matching condition returns false" do
466
507
  mock_app {
467
508
  condition { params[:foo] == 'bar' }
@@ -781,4 +822,39 @@ class RoutingTest < Test::Unit::TestCase
781
822
  end
782
823
 
783
824
  end
825
+
826
+ it "matches routes defined in superclasses" do
827
+ base = Class.new(Sinatra::Base)
828
+ base.get('/foo') { 'foo in baseclass' }
829
+
830
+ mock_app(base) {
831
+ get('/bar') { 'bar in subclass' }
832
+ }
833
+
834
+ get '/foo'
835
+ assert ok?
836
+ assert_equal 'foo in baseclass', body
837
+
838
+ get '/bar'
839
+ assert ok?
840
+ assert_equal 'bar in subclass', body
841
+ end
842
+
843
+ it "matches routes in subclasses before superclasses" do
844
+ base = Class.new(Sinatra::Base)
845
+ base.get('/foo') { 'foo in baseclass' }
846
+ base.get('/bar') { 'bar in baseclass' }
847
+
848
+ mock_app(base) {
849
+ get('/foo') { 'foo in subclass' }
850
+ }
851
+
852
+ get '/foo'
853
+ assert ok?
854
+ assert_equal 'foo in subclass', body
855
+
856
+ get '/bar'
857
+ assert ok?
858
+ assert_equal 'bar in baseclass', body
859
+ end
784
860
  end
@@ -1,26 +1,27 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- class OptionsTest < Test::Unit::TestCase
3
+ class SettingsTest < Test::Unit::TestCase
4
4
  setup do
5
- @base = Sinatra.new(Sinatra::Base)
5
+ @base = Sinatra.new(Sinatra::Base)
6
+ @base.set :environment, :foo
7
+
6
8
  @application = Sinatra.new(Sinatra::Application)
7
- @base.set :environment, :development
8
- @application.set :environment, :development
9
+ @application.set :environment, :foo
9
10
  end
10
11
 
11
- it 'sets options to literal values' do
12
+ it 'sets settings to literal values' do
12
13
  @base.set(:foo, 'bar')
13
14
  assert @base.respond_to?(:foo)
14
15
  assert_equal 'bar', @base.foo
15
16
  end
16
17
 
17
- it 'sets options to Procs' do
18
+ it 'sets settings to Procs' do
18
19
  @base.set(:foo, Proc.new { 'baz' })
19
20
  assert @base.respond_to?(:foo)
20
21
  assert_equal 'baz', @base.foo
21
22
  end
22
23
 
23
- it "sets multiple options with a Hash" do
24
+ it "sets multiple settings with a Hash" do
24
25
  @base.set :foo => 1234,
25
26
  :bar => 'Hello World',
26
27
  :baz => Proc.new { 'bizzle' }
@@ -29,7 +30,7 @@ class OptionsTest < Test::Unit::TestCase
29
30
  assert_equal 'bizzle', @base.baz
30
31
  end
31
32
 
32
- it 'inherits option methods when subclassed' do
33
+ it 'inherits settings methods when subclassed' do
33
34
  @base.set :foo, 'bar'
34
35
  @base.set :biz, Proc.new { 'baz' }
35
36
 
@@ -40,7 +41,7 @@ class OptionsTest < Test::Unit::TestCase
40
41
  assert_equal 'baz', sub.biz
41
42
  end
42
43
 
43
- it 'overrides options in subclass' do
44
+ it 'overrides settings in subclass' do
44
45
  @base.set :foo, 'bar'
45
46
  @base.set :biz, Proc.new { 'baz' }
46
47
  sub = Class.new(@base)
@@ -78,27 +79,42 @@ class OptionsTest < Test::Unit::TestCase
78
79
  assert_equal 'oops', @base.foo
79
80
  end
80
81
 
81
- it "sets multiple options to true with #enable" do
82
+ it "sets multiple settings to true with #enable" do
82
83
  @base.enable :sessions, :foo, :bar
83
84
  assert @base.sessions
84
85
  assert @base.foo
85
86
  assert @base.bar
86
87
  end
87
88
 
88
- it "sets multiple options to false with #disable" do
89
+ it "sets multiple settings to false with #disable" do
89
90
  @base.disable :sessions, :foo, :bar
90
91
  assert !@base.sessions
91
92
  assert !@base.foo
92
93
  assert !@base.bar
93
94
  end
94
95
 
95
- it 'enables MethodOverride middleware when :methodoverride is enabled' do
96
- @base.set :methodoverride, true
97
- @base.put('/') { 'okay' }
98
- @app = @base
99
- post '/', {'_method'=>'PUT'}, {}
100
- assert_equal 200, status
101
- assert_equal 'okay', body
96
+
97
+ it 'is accessible from instances via #settings' do
98
+ assert_equal :foo, @base.new.settings.environment
99
+ end
100
+
101
+ describe 'methodoverride' do
102
+ it 'is disabled on Base' do
103
+ assert ! @base.methodoverride?
104
+ end
105
+
106
+ it 'is enabled on Application' do
107
+ assert @application.methodoverride?
108
+ end
109
+
110
+ it 'enables MethodOverride middleware' do
111
+ @base.set :methodoverride, true
112
+ @base.put('/') { 'okay' }
113
+ @app = @base
114
+ post '/', {'_method'=>'PUT'}, {}
115
+ assert_equal 200, status
116
+ assert_equal 'okay', body
117
+ end
102
118
  end
103
119
 
104
120
  describe 'clean_trace' do
@@ -152,32 +168,22 @@ class OptionsTest < Test::Unit::TestCase
152
168
  assert ! @base.run?
153
169
  end
154
170
 
155
- it 'is enabled on Application when not in test environment' do
156
- @application.set :environment, :development
157
- assert @application.development?
171
+ it 'is enabled on Application except in test environment' do
158
172
  assert @application.run?
159
173
 
160
- @application.set :environment, :development
161
- assert @application.run?
174
+ @application.set :environment, :test
175
+ assert ! @application.run?
162
176
  end
163
-
164
- # TODO: it 'is enabled when $0 == app_file'
165
177
  end
166
178
 
167
179
  describe 'raise_errors' do
168
180
  it 'is enabled on Base except under development' do
169
- @base.environment = :test
170
181
  assert @base.raise_errors?
171
182
  @base.environment = :development
172
183
  assert !@base.raise_errors?
173
184
  end
174
185
 
175
186
  it 'is enabled on Application only in test' do
176
- @application.set(:environment, :development)
177
- assert @application.development?
178
- assert ! @application.raise_errors?
179
-
180
- @application.set(:environment, :production)
181
187
  assert ! @application.raise_errors?
182
188
 
183
189
  @application.set(:environment, :test)
@@ -187,22 +193,16 @@ class OptionsTest < Test::Unit::TestCase
187
193
 
188
194
  describe 'show_exceptions' do
189
195
  it 'is disabled on Base except under development' do
190
- @base.environment = :test
191
196
  assert ! @base.show_exceptions?
192
197
  @base.environment = :development
193
198
  assert @base.show_exceptions?
194
199
  end
195
200
 
196
- it 'is enabled on Application only in development' do
197
- @base.set(:environment, :development)
198
- assert @application.development?
199
- assert @application.show_exceptions?
200
-
201
- @application.set(:environment, :test)
201
+ it 'is disabled on Application except in development' do
202
202
  assert ! @application.show_exceptions?
203
203
 
204
- @base.set(:environment, :production)
205
- assert ! @base.show_exceptions?
204
+ @application.set(:environment, :development)
205
+ assert @application.show_exceptions?
206
206
  end
207
207
 
208
208
  it 'returns a friendly 500' do
@@ -224,7 +224,6 @@ class OptionsTest < Test::Unit::TestCase
224
224
 
225
225
  describe 'dump_errors' do
226
226
  it 'is disabled on Base except in development' do
227
- @base.environment = :test
228
227
  assert ! @base.dump_errors?
229
228
  @base.environment = :development
230
229
  assert @base.dump_errors?
@@ -253,7 +252,7 @@ class OptionsTest < Test::Unit::TestCase
253
252
  }
254
253
 
255
254
  get '/'
256
- assert body.include?("RuntimeError") && body.include?("options_test.rb")
255
+ assert body.include?("RuntimeError") && body.include?("settings_test.rb")
257
256
  end
258
257
  end
259
258
 
@@ -265,8 +264,6 @@ class OptionsTest < Test::Unit::TestCase
265
264
  it 'is disabled on Application' do
266
265
  assert ! @application.sessions?
267
266
  end
268
-
269
- # TODO: it 'uses Rack::Session::Cookie when enabled' do
270
267
  end
271
268
 
272
269
  describe 'logging' do
@@ -274,18 +271,16 @@ class OptionsTest < Test::Unit::TestCase
274
271
  assert ! @base.logging?
275
272
  end
276
273
 
277
- it 'is enabled on Application when not in test environment' do
274
+ it 'is enabled on Application except in test environment' do
278
275
  assert @application.logging?
279
276
 
280
277
  @application.set :environment, :test
281
278
  assert ! @application.logging
282
279
  end
283
-
284
- # TODO: it 'uses Rack::CommonLogger when enabled' do
285
280
  end
286
281
 
287
282
  describe 'static' do
288
- it 'is disabled on Base by Application' do
283
+ it 'is disabled on Base by default' do
289
284
  assert ! @base.static?
290
285
  end
291
286
 
@@ -329,8 +324,8 @@ class OptionsTest < Test::Unit::TestCase
329
324
 
330
325
  describe 'app_file' do
331
326
  it 'is nil' do
332
- assert @base.app_file.nil?
333
- assert @application.app_file.nil?
327
+ assert_nil @base.app_file
328
+ assert_nil @application.app_file
334
329
  end
335
330
  end
336
331
 
@@ -382,6 +377,7 @@ class OptionsTest < Test::Unit::TestCase
382
377
  describe 'lock' do
383
378
  it 'is disabled by default' do
384
379
  assert ! @base.lock?
380
+ assert ! @application.lock?
385
381
  end
386
382
  end
387
383
  end
@@ -26,6 +26,12 @@ class StaticTest < Test::Unit::TestCase
26
26
  assert_equal File.read(__FILE__), buf1.join
27
27
  end
28
28
 
29
+ it 'sets the sinatra.static_file env variable if served' do
30
+ env = Rack::MockRequest.env_for("/#{File.basename(__FILE__)}")
31
+ status, headers, body = @app.call(env)
32
+ assert_equal File.expand_path(__FILE__), env['sinatra.static_file']
33
+ end
34
+
29
35
  it 'serves HEAD requests for files in the public directory' do
30
36
  head "/#{File.basename(__FILE__)}"
31
37
  assert ok?
@@ -34,6 +40,13 @@ class StaticTest < Test::Unit::TestCase
34
40
  assert response.headers.include?('Last-Modified')
35
41
  end
36
42
 
43
+ %w[POST PUT DELETE].each do |verb|
44
+ it "does not serve #{verb} requests" do
45
+ send verb.downcase, "/#{File.basename(__FILE__)}"
46
+ assert_equal 404, status
47
+ end
48
+ end
49
+
37
50
  it 'serves files in preference to custom routes' do
38
51
  @app.get("/#{File.basename(__FILE__)}") { 'Hello World' }
39
52
  get "/#{File.basename(__FILE__)}"
@@ -1,12 +1,20 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
+ class TestTemplate < Tilt::Template
4
+ def compile!
5
+ end
6
+
7
+ def evaluate(scope, locals={}, &block)
8
+ inner = block ? block.call : ''
9
+ data + inner
10
+ end
11
+
12
+ Tilt.register 'test', self
13
+ end
14
+
3
15
  class TemplatesTest < Test::Unit::TestCase
4
- def render_app(&block)
5
- mock_app {
6
- def render_test(template, data, options, locals, &block)
7
- inner = block ? block.call : ''
8
- data + inner
9
- end
16
+ def render_app(base=Sinatra::Base, &block)
17
+ mock_app(base) {
10
18
  set :views, File.dirname(__FILE__) + '/views'
11
19
  get '/', &block
12
20
  template(:layout3) { "Layout 3!\n" }
@@ -68,12 +76,12 @@ class TemplatesTest < Test::Unit::TestCase
68
76
  assert_equal "Layout 3!\nHello World!\n", body
69
77
  end
70
78
 
71
- it 'loads templates from source file with inline templates' do
79
+ it 'loads templates from source file with inline_templates enabled' do
72
80
  mock_app {
73
81
  enable :inline_templates
74
82
  }
75
- assert_equal "this is foo\n\n", @app.templates[:foo][:template]
76
- assert_equal "X\n= yield\nX\n", @app.templates[:layout][:template]
83
+ assert_equal "this is foo\n\n", @app.templates[:foo][0]
84
+ assert_equal "X\n= yield\nX\n", @app.templates[:layout][0]
77
85
  end
78
86
 
79
87
  it 'loads templates from specified views directory' do
@@ -82,7 +90,7 @@ class TemplatesTest < Test::Unit::TestCase
82
90
  assert_equal "from another views directory\n", body
83
91
  end
84
92
 
85
- test 'inline_templates simply ignores IO errors' do
93
+ test 'use_in_file_templates simply ignores IO errors' do
86
94
  assert_nothing_raised {
87
95
  mock_app {
88
96
  set :inline_templates, '/foo/bar'
@@ -107,6 +115,31 @@ class TemplatesTest < Test::Unit::TestCase
107
115
  assert ok?
108
116
  assert_equal 'Hello Mike!<p>content</p>', body
109
117
  end
118
+
119
+ it 'loads templates defined in subclasses' do
120
+ base = Class.new(Sinatra::Base)
121
+ base.template(:foo) { 'bar' }
122
+ render_app(base) { render :test, :foo }
123
+ assert ok?
124
+ assert_equal 'bar', body
125
+ end
126
+
127
+ it 'uses templates in superclasses before subclasses' do
128
+ base = Class.new(Sinatra::Base)
129
+ base.template(:foo) { 'template in superclass' }
130
+ assert_equal 'template in superclass', base.templates[:foo].first.call
131
+
132
+ mock_app(base) {
133
+ set :views, File.dirname(__FILE__) + '/views'
134
+ template(:foo) { 'template in subclass' }
135
+ get('/') { render :test, :foo }
136
+ }
137
+ assert_equal 'template in subclass', @app.templates[:foo].first.call
138
+
139
+ get '/'
140
+ assert ok?
141
+ assert_equal 'template in subclass', body
142
+ end
110
143
  end
111
144
 
112
145
  # __END__ : this is not the real end of the script.