sinatra 0.9.1.1 → 0.9.2

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.

@@ -0,0 +1,145 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ require 'sass/error'
4
+
5
+ class RenderBacktraceTest < Test::Unit::TestCase
6
+ VIEWS = File.dirname(__FILE__) + '/views'
7
+
8
+ def assert_raise_at(filename, line, exception = RuntimeError)
9
+ f, l = nil
10
+ assert_raise(exception) do
11
+ begin
12
+ get('/')
13
+ rescue => e
14
+ f, l = e.backtrace.first.split(':')
15
+ raise
16
+ end
17
+ end
18
+ assert_equal(filename, f, "expected #{exception.name} in #{filename}, was #{f}")
19
+ assert_equal(line, l.to_i, "expected #{exception.name} in #{filename} at line #{line}, was at line #{l}")
20
+ end
21
+
22
+ def backtrace_app(&block)
23
+ mock_app {
24
+ use_in_file_templates!
25
+ set :views, RenderBacktraceTest::VIEWS
26
+ template :builder_template do
27
+ 'raise "error"'
28
+ end
29
+ template :erb_template do
30
+ '<% raise "error" %>'
31
+ end
32
+ template :haml_template do
33
+ '%h1= raise "error"'
34
+ end
35
+ template :sass_template do
36
+ '+syntax-error'
37
+ end
38
+ get '/', &block
39
+ }
40
+ end
41
+
42
+ it "provides backtrace for Builder template" do
43
+ backtrace_app { builder :error }
44
+ assert_raise_at(File.join(VIEWS,'error.builder'), 2)
45
+ end
46
+
47
+ it "provides backtrace for ERB template" do
48
+ backtrace_app { erb :error }
49
+ assert_raise_at(File.join(VIEWS,'error.erb'), 2)
50
+ end
51
+
52
+ it "provides backtrace for HAML template" do
53
+ backtrace_app { haml :error }
54
+ assert_raise_at(File.join(VIEWS,'error.haml'), 2)
55
+ end
56
+
57
+ it "provides backtrace for Sass template" do
58
+ backtrace_app { sass :error }
59
+ assert_raise_at(File.join(VIEWS,'error.sass'), 2, Sass::SyntaxError)
60
+ end
61
+
62
+ it "provides backtrace for ERB template with locals" do
63
+ backtrace_app { erb :error, {}, :french => true }
64
+ assert_raise_at(File.join(VIEWS,'error.erb'), 3)
65
+ end
66
+
67
+ it "provides backtrace for HAML template with locals" do
68
+ backtrace_app { haml :error, {}, :french => true }
69
+ assert_raise_at(File.join(VIEWS,'error.haml'), 3)
70
+ end
71
+
72
+ it "provides backtrace for inline Builder string" do
73
+ backtrace_app { builder "raise 'Ack! Thbbbt!'"}
74
+ assert_raise_at(__FILE__, (__LINE__-1))
75
+ end
76
+
77
+ it "provides backtrace for inline ERB string" do
78
+ backtrace_app { erb "<% raise 'bidi-bidi-bidi' %>" }
79
+ assert_raise_at(__FILE__, (__LINE__-1))
80
+ end
81
+
82
+ it "provides backtrace for inline HAML string" do
83
+ backtrace_app { haml "%h1= raise 'Lions and tigers and bears! Oh, my!'" }
84
+ assert_raise_at(__FILE__, (__LINE__-1))
85
+ end
86
+
87
+ # it "provides backtrace for inline Sass string" do
88
+ # backtrace_app { sass '+buh-bye' }
89
+ # assert_raise_at(__FILE__, (__LINE__-1), Sass::SyntaxError)
90
+ # end
91
+
92
+ it "provides backtrace for named Builder template" do
93
+ backtrace_app { builder :builder_template }
94
+ assert_raise_at(__FILE__, (__LINE__-68))
95
+ end
96
+
97
+ it "provides backtrace for named ERB template" do
98
+ backtrace_app { erb :erb_template }
99
+ assert_raise_at(__FILE__, (__LINE__-70))
100
+ end
101
+
102
+ it "provides backtrace for named HAML template" do
103
+ backtrace_app { haml :haml_template }
104
+ assert_raise_at(__FILE__, (__LINE__-72))
105
+ end
106
+
107
+ # it "provides backtrace for named Sass template" do
108
+ # backtrace_app { sass :sass_template }
109
+ # assert_raise_at(__FILE__, (__LINE__-74), Sass::SyntaxError)
110
+ # end
111
+
112
+ it "provides backtrace for in file Builder template" do
113
+ backtrace_app { builder :builder_in_file }
114
+ assert_raise_at(__FILE__, (__LINE__+22))
115
+ end
116
+
117
+ it "provides backtrace for in file ERB template" do
118
+ backtrace_app { erb :erb_in_file }
119
+ assert_raise_at(__FILE__, (__LINE__+20))
120
+ end
121
+
122
+ it "provides backtrace for in file HAML template" do
123
+ backtrace_app { haml :haml_in_file }
124
+ assert_raise_at(__FILE__, (__LINE__+18))
125
+ end
126
+
127
+ # it "provides backtrace for in file Sass template" do
128
+ # backtrace_app { sass :sass_in_file }
129
+ # assert_raise_at(__FILE__, (__LINE__+16), Sass::SyntaxError)
130
+ # end
131
+ end
132
+
133
+ __END__
134
+
135
+ @@ builder_in_file
136
+ raise "bif"
137
+
138
+ @@ erb_in_file
139
+ <% raise "bam" %>
140
+
141
+ @@ haml_in_file
142
+ %h1= raise "pow"
143
+
144
+ @@ sass_in_file
145
+ +blam
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Sinatra::Request' do
3
+ class RequestTest < Test::Unit::TestCase
4
4
  it 'responds to #user_agent' do
5
5
  request = Sinatra::Request.new({'HTTP_USER_AGENT' => 'Test'})
6
6
  assert request.respond_to?(:user_agent)
@@ -2,8 +2,8 @@
2
2
 
3
3
  require File.dirname(__FILE__) + '/helper'
4
4
 
5
- describe 'Sinatra::Response' do
6
- before do
5
+ class ResponseTest < Test::Unit::TestCase
6
+ setup do
7
7
  @response = Sinatra::Response.new
8
8
  end
9
9
 
@@ -1,6 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Result Handling' do
3
+ class ResultTest < Test::Unit::TestCase
4
4
  it "sets response.body when result is a String" do
5
5
  mock_app {
6
6
  get '/' do
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ module RouteAddedTest
4
+ @routes, @procs = [], []
5
+ def self.routes ; @routes ; end
6
+ def self.procs ; @procs ; end
7
+ def self.route_added(verb, path, proc)
8
+ @routes << [verb, path]
9
+ @procs << proc
10
+ end
11
+ end
12
+
13
+ class RouteAddedHookTest < Test::Unit::TestCase
14
+ setup {
15
+ RouteAddedTest.routes.clear
16
+ RouteAddedTest.procs.clear
17
+ }
18
+
19
+ it "should be notified of an added route" do
20
+ mock_app(Class.new(Sinatra::Base)) {
21
+ register RouteAddedTest
22
+ get('/') {}
23
+ }
24
+
25
+ assert_equal [["GET", "/"], ["HEAD", "/"]],
26
+ RouteAddedTest.routes
27
+ end
28
+
29
+ it "should include hooks from superclass" do
30
+ a = Class.new(Class.new(Sinatra::Base))
31
+ b = Class.new(a)
32
+
33
+ a.register RouteAddedTest
34
+ b.class_eval { post("/sub_app_route") {} }
35
+
36
+ assert_equal [["POST", "/sub_app_route"]],
37
+ RouteAddedTest.routes
38
+ end
39
+
40
+ it "should only run once per extension" do
41
+ mock_app(Class.new(Sinatra::Base)) {
42
+ register RouteAddedTest
43
+ register RouteAddedTest
44
+ get('/') {}
45
+ }
46
+
47
+ assert_equal [["GET", "/"], ["HEAD", "/"]],
48
+ RouteAddedTest.routes
49
+ end
50
+
51
+ it "should pass route blocks as an argument" do
52
+ mock_app(Class.new(Sinatra::Base)) {
53
+ register RouteAddedTest
54
+ get('/') {}
55
+ }
56
+
57
+ assert_kind_of Proc, RouteAddedTest.procs.first
58
+ end
59
+ end
@@ -5,7 +5,23 @@ def route_def(pattern)
5
5
  mock_app { get(pattern) { } }
6
6
  end
7
7
 
8
- describe "Routing" do
8
+ class RegexpLookAlike
9
+ class MatchData
10
+ def captures
11
+ ["this", "is", "a", "test"]
12
+ end
13
+ end
14
+
15
+ def match(string)
16
+ ::RegexpLookAlike::MatchData.new if string == "/this/is/a/test/"
17
+ end
18
+
19
+ def keys
20
+ ["one", "two", "three", "four"]
21
+ end
22
+ end
23
+
24
+ class RoutingTest < Test::Unit::TestCase
9
25
  %w[get put post delete].each do |verb|
10
26
  it "defines #{verb.upcase} request handlers with #{verb}" do
11
27
  mock_app {
@@ -44,6 +60,21 @@ describe "Routing" do
44
60
  assert_equal 404, status
45
61
  end
46
62
 
63
+ it "overrides the content-type in error handlers" do
64
+ mock_app {
65
+ before { content_type 'text/plain' }
66
+ error Sinatra::NotFound do
67
+ content_type "text/html"
68
+ "<h1>Not Found</h1>"
69
+ end
70
+ }
71
+
72
+ get '/foo'
73
+ assert_equal 404, status
74
+ assert_equal 'text/html', response["Content-Type"]
75
+ assert_equal "<h1>Not Found</h1>", response.body
76
+ end
77
+
47
78
  it 'takes multiple definitions of a route' do
48
79
  mock_app {
49
80
  user_agent(/Foo/)
@@ -243,17 +274,7 @@ describe "Routing" do
243
274
  end
244
275
 
245
276
  it "supports deeply nested params" do
246
- input = {
247
- 'browser[chrome][engine][name]' => 'V8',
248
- 'browser[chrome][engine][version]' => '1.0',
249
- 'browser[firefox][engine][name]' => 'spidermonkey',
250
- 'browser[firefox][engine][version]' => '1.7.0',
251
- 'emacs[map][goto-line]' => 'M-g g',
252
- 'emacs[version]' => '22.3.1',
253
- 'paste[name]' => 'hello world',
254
- 'paste[syntax]' => 'ruby'
255
- }
256
- expected = {
277
+ expected_params = {
257
278
  "emacs" => {
258
279
  "map" => { "goto-line" => "M-g g" },
259
280
  "version" => "22.3.1"
@@ -266,11 +287,11 @@ describe "Routing" do
266
287
  }
267
288
  mock_app {
268
289
  get '/foo' do
269
- assert_equal expected, params
290
+ assert_equal expected_params, params
270
291
  'looks good'
271
292
  end
272
293
  }
273
- get "/foo?#{build_query(input)}"
294
+ get '/foo', expected_params
274
295
  assert ok?
275
296
  assert_equal 'looks good', body
276
297
  end
@@ -352,9 +373,26 @@ describe "Routing" do
352
373
  assert_equal 'right on', body
353
374
  end
354
375
 
376
+ it 'supports regular expression look-alike routes' do
377
+ mock_app {
378
+ get(RegexpLookAlike.new) do
379
+ assert_equal 'this', params[:one]
380
+ assert_equal 'is', params[:two]
381
+ assert_equal 'a', params[:three]
382
+ assert_equal 'test', params[:four]
383
+ 'right on'
384
+ end
385
+ }
386
+
387
+ get '/this/is/a/test/'
388
+ assert ok?
389
+ assert_equal 'right on', body
390
+ end
391
+
355
392
  it 'raises a TypeError when pattern is not a String or Regexp' do
356
- @app = mock_app
357
- assert_raise(TypeError) { @app.get(42){} }
393
+ assert_raise(TypeError) {
394
+ mock_app { get(42){} }
395
+ }
358
396
  end
359
397
 
360
398
  it "returns response immediately on halt" do
@@ -479,7 +517,7 @@ describe "Routing" do
479
517
  get '/foo'
480
518
  assert not_found?
481
519
 
482
- get '/foo', :env => { 'HTTP_HOST' => 'example.com' }
520
+ get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
483
521
  assert_equal 200, status
484
522
  assert_equal 'Hello World', body
485
523
  end
@@ -494,7 +532,7 @@ describe "Routing" do
494
532
  get '/foo'
495
533
  assert not_found?
496
534
 
497
- get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
535
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'Foo Bar' }
498
536
  assert_equal 200, status
499
537
  assert_equal 'Hello World', body
500
538
  end
@@ -506,7 +544,7 @@ describe "Routing" do
506
544
  'Hello ' + params[:agent].first
507
545
  end
508
546
  }
509
- get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
547
+ get '/foo', {}, { 'HTTP_USER_AGENT' => 'Foo Bar' }
510
548
  assert_equal 200, status
511
549
  assert_equal 'Hello Bar', body
512
550
  end
@@ -518,12 +556,12 @@ describe "Routing" do
518
556
  end
519
557
  }
520
558
 
521
- get '/', :env => { :accept => 'application/xml' }
559
+ get '/', {}, { 'HTTP_ACCEPT' => 'application/xml' }
522
560
  assert ok?
523
561
  assert_equal 'application/xml', body
524
562
  assert_equal 'application/xml', response.headers['Content-Type']
525
563
 
526
- get '/', :env => { :accept => 'text/html' }
564
+ get '/', {}, { :accept => 'text/html' }
527
565
  assert !ok?
528
566
  end
529
567
 
@@ -537,7 +575,7 @@ describe "Routing" do
537
575
  }
538
576
 
539
577
  types.each do |type|
540
- get '/', :env => { :accept => type }
578
+ get '/', {}, { 'HTTP_ACCEPT' => type }
541
579
  assert ok?
542
580
  assert_equal type, body
543
581
  assert_equal type, response.headers['Content-Type']
@@ -655,6 +693,40 @@ describe "Routing" do
655
693
  assert_equal 'ab', body
656
694
  end
657
695
 
696
+ it 'allows custom route-conditions to be set via route options' do
697
+ protector = Module.new {
698
+ def protect(*args)
699
+ condition {
700
+ unless authorize(params["user"], params["password"])
701
+ halt 403, "go away"
702
+ end
703
+ }
704
+ end
705
+ }
706
+
707
+ mock_app {
708
+ register protector
709
+
710
+ helpers do
711
+ def authorize(username, password)
712
+ username == "foo" && password == "bar"
713
+ end
714
+ end
715
+
716
+ get "/", :protect => true do
717
+ "hey"
718
+ end
719
+ }
720
+
721
+ get "/"
722
+ assert forbidden?
723
+ assert_equal "go away", body
724
+
725
+ get "/", :user => "foo", :password => "bar"
726
+ assert ok?
727
+ assert_equal "hey", body
728
+ end
729
+
658
730
  # NOTE Block params behaves differently under 1.8 and 1.9. Under 1.8, block
659
731
  # param arity is lax: declaring a mismatched number of block params results
660
732
  # in a warning. Under 1.9, block param arity is strict: mismatched block
@@ -1,6 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
+ require 'sass'
2
3
 
3
- describe "Sass Templates" do
4
+ class SassTest < Test::Unit::TestCase
4
5
  def sass_app(&block)
5
6
  mock_app {
6
7
  set :views, File.dirname(__FILE__) + '/views'
@@ -33,4 +34,46 @@ describe "Sass Templates" do
33
34
  }
34
35
  assert_raise(Errno::ENOENT) { get('/') }
35
36
  end
37
+
38
+ it "passes SASS options to the Sass engine" do
39
+ sass_app {
40
+ sass "#sass\n :background-color #FFF\n :color #000\n", :style => :compact
41
+ }
42
+ assert ok?
43
+ assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
44
+ end
45
+
46
+ it "passes default SASS options to the Sass engine" do
47
+ mock_app {
48
+ set :sass, {:style => :compact} # default Sass style is :nested
49
+ get '/' do
50
+ sass "#sass\n :background-color #FFF\n :color #000\n"
51
+ end
52
+ }
53
+ get '/'
54
+ assert ok?
55
+ assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
56
+ end
57
+
58
+ it "merges the default SASS options with the overrides and passes them to the Sass engine" do
59
+ mock_app {
60
+ set :sass, {:style => :compact, :attribute_syntax => :alternate } # default Sass attribute_syntax is :normal (with : in front)
61
+ get '/' do
62
+ sass "#sass\n background-color: #FFF\n color: #000\n"
63
+ end
64
+ get '/raised' do
65
+ sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded # retains global attribute_syntax settings
66
+ end
67
+ get '/expanded_normal' do
68
+ sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded, :attribute_syntax => :normal
69
+ end
70
+ }
71
+ get '/'
72
+ assert ok?
73
+ assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
74
+ assert_raise(Sass::SyntaxError) { get('/raised') }
75
+ get '/expanded_normal'
76
+ assert ok?
77
+ assert_equal "#sass {\n background-color: #FFF;\n color: #000;\n}\n", body
78
+ end
36
79
  end