sinatra-sinatra 0.9.0.4 → 0.9.0.5

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/lib/sinatra/test.rb CHANGED
@@ -7,7 +7,7 @@ module Sinatra
7
7
 
8
8
  attr_reader :app, :request, :response
9
9
 
10
- def test_request(verb, path, *args)
10
+ def make_request(verb, path, *args)
11
11
  @app = Sinatra::Application if @app.nil? && defined?(Sinatra::Application)
12
12
  fail "@app not set - cannot make request" if @app.nil?
13
13
  @request = Rack::MockRequest.new(@app)
@@ -38,14 +38,14 @@ module Sinatra
38
38
  @response = @request.request(verb, path, opts)
39
39
  end
40
40
 
41
- def get(path, *args, &b) ; test_request('GET', path, *args, &b) ; end
42
- def head(path, *args, &b) ; test_request('HEAD', path, *args, &b) ; end
43
- def post(path, *args, &b) ; test_request('POST', path, *args, &b) ; end
44
- def put(path, *args, &b) ; test_request('PUT', path, *args, &b) ; end
45
- def delete(path, *args, &b) ; test_request('DELETE', path, *args, &b) ; end
41
+ def get(path, *args, &b) ; make_request('GET', path, *args, &b) ; end
42
+ def head(path, *args, &b) ; make_request('HEAD', path, *args, &b) ; end
43
+ def post(path, *args, &b) ; make_request('POST', path, *args, &b) ; end
44
+ def put(path, *args, &b) ; make_request('PUT', path, *args, &b) ; end
45
+ def delete(path, *args, &b) ; make_request('DELETE', path, *args, &b) ; end
46
46
 
47
47
  def follow!
48
- test_request 'GET', @response.location
48
+ make_request 'GET', @response.location
49
49
  end
50
50
 
51
51
  def body ; @response.body ; end
@@ -65,6 +65,8 @@ module Sinatra
65
65
  super || (@response && @response.respond_to?(symbol, include_private))
66
66
  end
67
67
 
68
+ private
69
+
68
70
  RACK_OPT_NAMES = {
69
71
  :accept => "HTTP_ACCEPT",
70
72
  :agent => "HTTP_USER_AGENT",
@@ -103,7 +105,7 @@ module Sinatra
103
105
  eval <<-RUBY, binding, __FILE__, __LINE__
104
106
  def #{verb}_it(*args, &block)
105
107
  sinatra_warn "The #{verb}_it method is deprecated; use #{verb} instead."
106
- test_request('#{verb.upcase}', *args, &block)
108
+ make_request('#{verb.upcase}', *args, &block)
107
109
  end
108
110
  RUBY
109
111
  end
data/sinatra.gemspec CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
4
 
5
5
  s.name = 'sinatra'
6
- s.version = '0.9.0.4'
7
- s.date = '2009-01-25'
6
+ s.version = '0.9.0.5'
7
+ s.date = '2009-02-10'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  compat/app_test.rb
23
23
  compat/application_test.rb
24
24
  compat/builder_test.rb
25
+ compat/compat_test.rb
25
26
  compat/custom_error_test.rb
26
27
  compat/erb_test.rb
27
28
  compat/events_test.rb
@@ -69,6 +70,7 @@ Gem::Specification.new do |s|
69
70
  test/builder_test.rb
70
71
  test/data/reload_app_file.rb
71
72
  test/erb_test.rb
73
+ test/extensions_test.rb
72
74
  test/filter_test.rb
73
75
  test/haml_test.rb
74
76
  test/helper.rb
@@ -78,12 +80,15 @@ Gem::Specification.new do |s|
78
80
  test/options_test.rb
79
81
  test/reload_test.rb
80
82
  test/request_test.rb
83
+ test/response_test.rb
81
84
  test/result_test.rb
82
85
  test/routing_test.rb
83
86
  test/sass_test.rb
87
+ test/server_test.rb
84
88
  test/sinatra_test.rb
85
89
  test/static_test.rb
86
90
  test/templates_test.rb
91
+ test/test_test.rb
87
92
  test/views/hello.builder
88
93
  test/views/hello.erb
89
94
  test/views/hello.haml
data/test/base_test.rb CHANGED
@@ -65,4 +65,17 @@ describe 'Sinatra::Base' do
65
65
  assert response.ok?
66
66
  assert_equal 'not foo', response.body
67
67
  end
68
+
69
+ it "makes redirecting back pretty" do
70
+ app = mock_app {
71
+ get '/foo' do
72
+ redirect back
73
+ end
74
+ }
75
+
76
+ request = Rack::MockRequest.new(app)
77
+ response = request.get('/foo', 'HTTP_REFERER' => 'http://github.com')
78
+ assert response.redirect?
79
+ assert_equal "http://github.com", response.location
80
+ end
68
81
  end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe 'Registering extensions' do
4
+ module FooExtensions
5
+ def foo
6
+ end
7
+
8
+ private
9
+ def im_hiding_in_ur_foos
10
+ end
11
+ end
12
+
13
+ module BarExtensions
14
+ def bar
15
+ end
16
+ end
17
+
18
+ module BazExtensions
19
+ def baz
20
+ end
21
+ end
22
+
23
+ module QuuxExtensions
24
+ def quux
25
+ end
26
+ end
27
+
28
+ it 'will add the methods to the DSL for the class in which you register them and its subclasses' do
29
+ Sinatra::Base.register FooExtensions
30
+ assert Sinatra::Base.respond_to?(:foo)
31
+
32
+ Sinatra::Default.register BarExtensions
33
+ assert Sinatra::Default.respond_to?(:bar)
34
+ assert Sinatra::Default.respond_to?(:foo)
35
+ assert !Sinatra::Base.respond_to?(:bar)
36
+ end
37
+
38
+ it 'allows extending by passing a block' do
39
+ Sinatra::Base.register {
40
+ def im_in_ur_anonymous_module; end
41
+ }
42
+ assert Sinatra::Base.respond_to?(:im_in_ur_anonymous_module)
43
+ end
44
+
45
+ it 'will make sure any public methods added via Default#register are delegated to Sinatra::Delegator' do
46
+ Sinatra::Default.register FooExtensions
47
+ assert Sinatra::Delegator.private_instance_methods.
48
+ map { |m| m.to_sym }.include?(:foo)
49
+ assert !Sinatra::Delegator.private_instance_methods.
50
+ map { |m| m.to_sym }.include?(:im_hiding_in_ur_foos)
51
+ end
52
+
53
+ it 'will not delegate methods on Base#register' do
54
+ Sinatra::Base.register QuuxExtensions
55
+ assert !Sinatra::Delegator.private_instance_methods.include?("quux")
56
+ end
57
+
58
+ it 'will extend the Sinatra::Default application by default' do
59
+ Sinatra.register BazExtensions
60
+ assert !Sinatra::Base.respond_to?(:baz)
61
+ assert Sinatra::Default.respond_to?(:baz)
62
+ end
63
+ end
data/test/helper.rb CHANGED
@@ -32,9 +32,12 @@ end
32
32
  #
33
33
  def describe(*args, &block)
34
34
  return super unless (name = args.first) && block
35
- klass = Class.new(Test::Unit::TestCase) do
35
+ name = "#{name.gsub(/\W/, '')}Test"
36
+ Object.send :const_set, name, Class.new(Test::Unit::TestCase)
37
+ klass = Object.const_get(name)
38
+ klass.class_eval do
36
39
  def self.it(name, &block)
37
- define_method("test_#{name.gsub(/\W/,'_')}", &block)
40
+ define_method("test_#{name.gsub(/\W/,'_').downcase}", &block)
38
41
  end
39
42
  def self.xspecify(*args) end
40
43
  def self.before(&block) define_method(:setup, &block) end
@@ -42,3 +45,11 @@ def describe(*args, &block)
42
45
  end
43
46
  klass.class_eval &block
44
47
  end
48
+
49
+ # Do not output warnings for the duration of the block.
50
+ def silence_warnings
51
+ $VERBOSE, v = nil, $VERBOSE
52
+ yield
53
+ ensure
54
+ $VERBOSE = v
55
+ end
data/test/helpers_test.rb CHANGED
@@ -379,3 +379,61 @@ describe 'Helpers#etag' do
379
379
  assert_equal 'W/"FOO"', response['ETag']
380
380
  end
381
381
  end
382
+
383
+ module HelperOne; def one; '1'; end; end
384
+ module HelperTwo; def two; '2'; end; end
385
+
386
+ describe 'Adding new helpers' do
387
+ it 'takes a list of modules to mix into the app' do
388
+ mock_app {
389
+ helpers HelperOne, HelperTwo
390
+
391
+ get '/one' do
392
+ one
393
+ end
394
+
395
+ get '/two' do
396
+ two
397
+ end
398
+ }
399
+
400
+ get '/one'
401
+ assert_equal '1', body
402
+
403
+ get '/two'
404
+ assert_equal '2', body
405
+ end
406
+
407
+ it 'takes a block to mix into the app' do
408
+ mock_app {
409
+ helpers do
410
+ def foo
411
+ 'foo'
412
+ end
413
+ end
414
+
415
+ get '/' do
416
+ foo
417
+ end
418
+ }
419
+
420
+ get '/'
421
+ assert_equal 'foo', body
422
+ end
423
+
424
+ it 'evaluates the block in class context so that methods can be aliased' do
425
+ mock_app {
426
+ helpers do
427
+ alias_method :h, :escape_html
428
+ end
429
+
430
+ get '/' do
431
+ h('42 < 43')
432
+ end
433
+ }
434
+
435
+ get '/'
436
+ assert ok?
437
+ assert_equal '42 &lt; 43', body
438
+ end
439
+ end
@@ -1,9 +1,12 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Exception Mappings' do
4
- class FooError < RuntimeError
5
- end
3
+ class FooError < RuntimeError
4
+ end
6
5
 
6
+ class FooNotFound < Sinatra::NotFound
7
+ end
8
+
9
+ describe 'Exception Mappings' do
7
10
  it 'invokes handlers registered with ::error when raised' do
8
11
  mock_app {
9
12
  set :raise_errors, false
@@ -80,9 +83,6 @@ describe 'Exception Mappings' do
80
83
  assert_equal 404, status
81
84
  end
82
85
 
83
- class FooNotFound < Sinatra::NotFound
84
- end
85
-
86
86
  it "cascades for subclasses of Sinatra::NotFound" do
87
87
  mock_app {
88
88
  set :raise_errors, true
@@ -4,7 +4,9 @@ describe "Middleware" do
4
4
  before do
5
5
  @app = mock_app(Sinatra::Default) {
6
6
  get '/*' do
7
- response.headers['X-Tests'] = env['test.ran'].join(', ')
7
+ response.headers['X-Tests'] = env['test.ran'].
8
+ map { |n| n.split('::').last }.
9
+ join(', ')
8
10
  env['PATH_INFO']
9
11
  end
10
12
  }
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/helper'
4
+
5
+ describe 'Sinatra::Response' do
6
+ before do
7
+ @response = Sinatra::Response.new
8
+ end
9
+
10
+ it "initializes with 200, text/html, and empty body" do
11
+ assert_equal 200, @response.status
12
+ assert_equal 'text/html', @response['Content-Type']
13
+ assert_equal [], @response.body
14
+ end
15
+
16
+ it 'uses case insensitive headers' do
17
+ @response['content-type'] = 'application/foo'
18
+ assert_equal 'application/foo', @response['Content-Type']
19
+ assert_equal 'application/foo', @response['CONTENT-TYPE']
20
+ end
21
+
22
+ it 'writes to body' do
23
+ @response.body = 'Hello'
24
+ @response.write ' World'
25
+ assert_equal 'Hello World', @response.body
26
+ end
27
+
28
+ [204, 304].each do |status_code|
29
+ it "removes the Content-Type header and body when response status is #{status_code}" do
30
+ @response.status = status_code
31
+ @response.body = ['Hello World']
32
+ assert_equal [status_code, {}, []], @response.finish
33
+ end
34
+ end
35
+
36
+ it 'Calculates the Content-Length using the bytesize of the body' do
37
+ @response.body = ['Hello', 'World!', '✈']
38
+ status, headers, body = @response.finish
39
+ assert_equal '14', headers['Content-Length']
40
+ assert_equal @response.body, body
41
+ end
42
+ end
data/test/routing_test.rb CHANGED
@@ -484,4 +484,170 @@ describe "Routing" do
484
484
  assert_equal type, response.headers['Content-Type']
485
485
  end
486
486
  end
487
+
488
+ it 'degrades gracefully when optional accept header is not provided' do
489
+ mock_app {
490
+ get '/', :provides => :xml do
491
+ request.env['HTTP_ACCEPT']
492
+ end
493
+ get '/' do
494
+ 'default'
495
+ end
496
+ }
497
+ get '/'
498
+ assert ok?
499
+ assert_equal 'default', body
500
+ end
501
+
502
+ it 'passes a single url param as block parameters when one param is specified' do
503
+ mock_app {
504
+ get '/:foo' do |foo|
505
+ assert_equal 'bar', foo
506
+ end
507
+ }
508
+
509
+ get '/bar'
510
+ assert ok?
511
+ end
512
+
513
+ it 'passes multiple params as block parameters when many are specified' do
514
+ mock_app {
515
+ get '/:foo/:bar/:baz' do |foo, bar, baz|
516
+ assert_equal 'abc', foo
517
+ assert_equal 'def', bar
518
+ assert_equal 'ghi', baz
519
+ end
520
+ }
521
+
522
+ get '/abc/def/ghi'
523
+ assert ok?
524
+ end
525
+
526
+ it 'passes regular expression captures as block parameters' do
527
+ mock_app {
528
+ get(/^\/fo(.*)\/ba(.*)/) do |foo, bar|
529
+ assert_equal 'orooomma', foo
530
+ assert_equal 'f', bar
531
+ 'looks good'
532
+ end
533
+ }
534
+
535
+ get '/foorooomma/baf'
536
+ assert ok?
537
+ assert_equal 'looks good', body
538
+ end
539
+
540
+ it "supports mixing multiple splat params like /*/foo/*/* as block parameters" do
541
+ mock_app {
542
+ get '/*/foo/*/*' do |foo, bar, baz|
543
+ assert_equal 'bar', foo
544
+ assert_equal 'bling', bar
545
+ assert_equal 'baz/boom', baz
546
+ 'looks good'
547
+ end
548
+ }
549
+
550
+ get '/bar/foo/bling/baz/boom'
551
+ assert ok?
552
+ assert_equal 'looks good', body
553
+ end
554
+
555
+ it 'raises an ArgumentError with block arity > 1 and too many values' do
556
+ mock_app {
557
+ get '/:foo/:bar/:baz' do |foo, bar|
558
+ 'quux'
559
+ end
560
+ }
561
+
562
+ assert_raise(ArgumentError) { get '/a/b/c' }
563
+ end
564
+
565
+ it 'raises an ArgumentError with block param arity > 1 and too few values' do
566
+ mock_app {
567
+ get '/:foo/:bar' do |foo, bar, baz|
568
+ 'quux'
569
+ end
570
+ }
571
+
572
+ assert_raise(ArgumentError) { get '/a/b' }
573
+ end
574
+
575
+ it 'succeeds if no block parameters are specified' do
576
+ mock_app {
577
+ get '/:foo/:bar' do
578
+ 'quux'
579
+ end
580
+ }
581
+
582
+ get '/a/b'
583
+ assert ok?
584
+ assert_equal 'quux', body
585
+ end
586
+
587
+ it 'passes all params with block param arity -1 (splat args)' do
588
+ mock_app {
589
+ get '/:foo/:bar' do |*args|
590
+ args.join
591
+ end
592
+ }
593
+
594
+ get '/a/b'
595
+ assert ok?
596
+ assert_equal 'ab', body
597
+ end
598
+
599
+ # NOTE Block params behaves differently under 1.8 and 1.9. Under 1.8, block
600
+ # param arity is lax: declaring a mismatched number of block params results
601
+ # in a warning. Under 1.9, block param arity is strict: mismatched block
602
+ # arity raises an ArgumentError.
603
+
604
+ if RUBY_VERSION >= '1.9'
605
+
606
+ it 'raises an ArgumentError with block param arity 1 and no values' do
607
+ mock_app {
608
+ get '/foo' do |foo|
609
+ 'quux'
610
+ end
611
+ }
612
+
613
+ assert_raise(ArgumentError) { get '/foo' }
614
+ end
615
+
616
+ it 'raises an ArgumentError with block param arity 1 and too many values' do
617
+ mock_app {
618
+ get '/:foo/:bar/:baz' do |foo|
619
+ 'quux'
620
+ end
621
+ }
622
+
623
+ assert_raise(ArgumentError) { get '/a/b/c' }
624
+ end
625
+
626
+ else
627
+
628
+ it 'does not raise an ArgumentError with block param arity 1 and no values' do
629
+ mock_app {
630
+ get '/foo' do |foo|
631
+ 'quux'
632
+ end
633
+ }
634
+
635
+ silence_warnings { get '/foo' }
636
+ assert ok?
637
+ assert_equal 'quux', body
638
+ end
639
+
640
+ it 'does not raise an ArgumentError with block param arity 1 and too many values' do
641
+ mock_app {
642
+ get '/:foo/:bar/:baz' do |foo|
643
+ 'quux'
644
+ end
645
+ }
646
+
647
+ silence_warnings { get '/a/b/c' }
648
+ assert ok?
649
+ assert_equal 'quux', body
650
+ end
651
+
652
+ end
487
653
  end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class Rack::Handler::Mock
4
+ extend Test::Unit::Assertions
5
+
6
+ def self.run(app, options={})
7
+ assert(app < Sinatra::Base)
8
+ assert_equal 9001, options[:Port]
9
+ assert_equal 'foo.local', options[:Host]
10
+ yield new
11
+ end
12
+
13
+ def stop
14
+ end
15
+ end
16
+
17
+ describe 'Sinatra::Base.run!' do
18
+ before do
19
+ mock_app {
20
+ set :server, 'mock'
21
+ set :host, 'foo.local'
22
+ set :port, 9001
23
+ }
24
+ $stdout = File.open('/dev/null', 'wb')
25
+ end
26
+
27
+ after { $stdout = STDOUT }
28
+
29
+ it "locates the appropriate Rack handler and calls ::run" do
30
+ @app.run!
31
+ end
32
+
33
+ it "sets options on the app before running" do
34
+ @app.run! :sessions => true
35
+ assert @app.sessions?
36
+ end
37
+
38
+ it "falls back on the next server handler when not found" do
39
+ @app.run! :server => %w[foo bar mock]
40
+ end
41
+ end
data/test/static_test.rb CHANGED
@@ -1,17 +1,15 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
3
  describe 'Static' do
4
- F = ::File
5
-
6
4
  before do
7
5
  mock_app {
8
6
  set :static, true
9
- set :public, F.dirname(__FILE__)
7
+ set :public, File.dirname(__FILE__)
10
8
  }
11
9
  end
12
10
 
13
11
  it 'serves GET requests for files in the public directory' do
14
- get "/#{F.basename(__FILE__)}"
12
+ get "/#{File.basename(__FILE__)}"
15
13
  assert ok?
16
14
  assert_equal File.read(__FILE__), body
17
15
  assert_equal File.size(__FILE__).to_s, response['Content-Length']
@@ -19,7 +17,7 @@ describe 'Static' do
19
17
  end
20
18
 
21
19
  it 'produces a body that can be iterated over multiple times' do
22
- env = Rack::MockRequest.env_for("/#{F.basename(__FILE__)}")
20
+ env = Rack::MockRequest.env_for("/#{File.basename(__FILE__)}")
23
21
  status, headers, body = @app.call(env)
24
22
  buf1, buf2 = [], []
25
23
  body.each { |part| buf1 << part }
@@ -29,7 +27,7 @@ describe 'Static' do
29
27
  end
30
28
 
31
29
  it 'serves HEAD requests for files in the public directory' do
32
- head "/#{F.basename(__FILE__)}"
30
+ head "/#{File.basename(__FILE__)}"
33
31
  assert ok?
34
32
  assert_equal '', body
35
33
  assert_equal File.size(__FILE__).to_s, response['Content-Length']
@@ -37,8 +35,8 @@ describe 'Static' do
37
35
  end
38
36
 
39
37
  it 'serves files in preference to custom routes' do
40
- @app.get("/#{F.basename(__FILE__)}") { 'Hello World' }
41
- get "/#{F.basename(__FILE__)}"
38
+ @app.get("/#{File.basename(__FILE__)}") { 'Hello World' }
39
+ get "/#{File.basename(__FILE__)}"
42
40
  assert ok?
43
41
  assert body != 'Hello World'
44
42
  end
@@ -50,13 +48,13 @@ describe 'Static' do
50
48
 
51
49
  it 'passes to the next handler when the static option is disabled' do
52
50
  @app.set :static, false
53
- get "/#{F.basename(__FILE__)}"
51
+ get "/#{File.basename(__FILE__)}"
54
52
  assert not_found?
55
53
  end
56
54
 
57
55
  it 'passes to the next handler when the public option is nil' do
58
56
  @app.set :public, nil
59
- get "/#{F.basename(__FILE__)}"
57
+ get "/#{File.basename(__FILE__)}"
60
58
  assert not_found?
61
59
  end
62
60
 
data/test/test_test.rb ADDED
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ describe "Sinatra::Test" do
4
+ it "support nested parameters" do
5
+ mock_app {
6
+ get '/' do
7
+ params[:post][:title]
8
+ end
9
+
10
+ post '/' do
11
+ params[:post][:content]
12
+ end
13
+ }
14
+
15
+ get '/', :post => { :title => 'My Post Title' }
16
+ assert_equal 'My Post Title', body
17
+
18
+ post '/', :post => { :content => 'Post Content' }
19
+ assert_equal 'Post Content', body
20
+ end
21
+ end