bmizerany-sinatra 0.9.0.5 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -106,6 +106,17 @@ module Sinatra
106
106
  etag(*args, &block)
107
107
  end
108
108
 
109
+ # Deprecated. Use the #attachment helper and return the data as a String or
110
+ # Array.
111
+ def send_data(data, options={})
112
+ sinatra_warn "The 'send_data' method is deprecated. use attachment, status, content_type, etc. helpers instead."
113
+
114
+ status options[:status] if options[:status]
115
+ attachment options[:filename] if options[:disposition] == 'attachment'
116
+ content_type options[:type] if options[:type]
117
+ halt data
118
+ end
119
+
109
120
  # Throwing halt with a Symbol and the to_result convention are
110
121
  # deprecated. Override the invoke method to detect those types of return
111
122
  # values.
@@ -1,41 +1,40 @@
1
1
  require 'sinatra/base'
2
2
 
3
3
  module Sinatra
4
-
5
4
  module Test
6
5
  include Rack::Utils
7
6
 
8
7
  attr_reader :app, :request, :response
9
8
 
10
- def make_request(verb, path, *args)
9
+ def self.deprecate(framework)
10
+ warn <<-EOF
11
+ Warning: support for the #{framework} testing framework is deprecated and
12
+ will be dropped in Sinatra 1.0. See <http://sinatra.github.com/testing.html>
13
+ for more information.
14
+ EOF
15
+ end
16
+
17
+ def make_request(verb, path, body=nil, options={})
11
18
  @app = Sinatra::Application if @app.nil? && defined?(Sinatra::Application)
12
19
  fail "@app not set - cannot make request" if @app.nil?
20
+
13
21
  @request = Rack::MockRequest.new(@app)
14
- opts, input =
15
- case args.size
16
- when 2 # input, env
17
- input, env = args
18
- if input.kind_of?(Hash) # params, env
19
- [env, param_string(input)]
20
- else
21
- [env, input]
22
- end
23
- when 1 # params
24
- if (data = args.first).kind_of?(Hash)
25
- env = (data.delete(:env) || {})
26
- [env, param_string(data)]
27
- else
28
- [{}, data]
29
- end
30
- when 0
31
- [{}, '']
32
- else
33
- raise ArgumentError, "zero, one, or two arguments expected"
34
- end
35
- opts = rack_opts(opts)
36
- opts[:input] ||= input
22
+ options = { :lint => true }.merge(options || {})
23
+
24
+ case
25
+ when body.respond_to?(:to_hash)
26
+ options.merge! body.delete(:env) if body.key?(:env)
27
+ options[:input] = param_string(body)
28
+ when body.respond_to?(:to_str)
29
+ options[:input] = body
30
+ when body.nil?
31
+ options[:input] = ''
32
+ else
33
+ raise ArgumentError, "body must be a Hash, String, or nil"
34
+ end
35
+
37
36
  yield @request if block_given?
38
- @response = @request.request(verb, path, opts)
37
+ @response = @request.request(verb, path, rack_options(options))
39
38
  end
40
39
 
41
40
  def get(path, *args, &b) ; make_request('GET', path, *args, &b) ; end
@@ -67,18 +66,18 @@ module Sinatra
67
66
 
68
67
  private
69
68
 
70
- RACK_OPT_NAMES = {
71
- :accept => "HTTP_ACCEPT",
72
- :agent => "HTTP_USER_AGENT",
73
- :host => "HTTP_HOST",
74
- :session => "HTTP_COOKIE",
75
- :cookies => "HTTP_COOKIE",
76
- :content_type => "CONTENT_TYPE"
69
+ RACK_OPTIONS = {
70
+ :accept => 'HTTP_ACCEPT',
71
+ :agent => 'HTTP_USER_AGENT',
72
+ :host => 'HTTP_HOST',
73
+ :session => 'rack.session',
74
+ :cookies => 'HTTP_COOKIE',
75
+ :content_type => 'CONTENT_TYPE'
77
76
  }
78
77
 
79
- def rack_opts(opts)
78
+ def rack_options(opts)
80
79
  opts.merge(:lint => true).inject({}) do |hash,(key,val)|
81
- key = RACK_OPT_NAMES[key] || key
80
+ key = RACK_OPTIONS[key] || key
82
81
  hash[key] = val
83
82
  hash
84
83
  end
@@ -1,6 +1,8 @@
1
1
  require 'bacon'
2
2
  require 'sinatra/test'
3
3
 
4
+ Sinatra::Test.deprecate('Bacon')
5
+
4
6
  Sinatra::Default.set(
5
7
  :environment => :test,
6
8
  :run => false,
@@ -3,6 +3,8 @@ require 'sinatra/test/unit'
3
3
  require 'spec'
4
4
  require 'spec/interop/test'
5
5
 
6
+ Sinatra::Test.deprecate('RSpec')
7
+
6
8
  Sinatra::Default.set(
7
9
  :environment => :test,
8
10
  :run => false,
@@ -2,6 +2,8 @@ require 'test/spec'
2
2
  require 'sinatra/test'
3
3
  require 'sinatra/test/unit'
4
4
 
5
+ Sinatra::Test.deprecate('test/spec')
6
+
5
7
  module Sinatra::Test
6
8
  def should
7
9
  @response.should
@@ -1,6 +1,8 @@
1
1
  require 'sinatra/test'
2
2
  require 'test/unit'
3
3
 
4
+ Sinatra::Test.deprecate('test/unit')
5
+
4
6
  Test::Unit::TestCase.send :include, Sinatra::Test
5
7
 
6
8
  Sinatra::Default.set(
@@ -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.5'
7
- s.date = '2009-02-10'
6
+ s.version = '0.9.1'
7
+ s.date = '2009-03-01'
8
8
 
9
9
  s.description = "Classy web-development dressed in a DSL"
10
10
  s.summary = "Classy web-development dressed in a DSL"
@@ -104,7 +104,7 @@ Gem::Specification.new do |s|
104
104
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
105
105
 
106
106
  s.extra_rdoc_files = %w[README.rdoc LICENSE]
107
- s.add_dependency 'rack', '>= 0.9.1'
107
+ s.add_dependency 'rack', '>= 0.9.1', '< 1.0'
108
108
 
109
109
  s.has_rdoc = true
110
110
  s.homepage = "http://sinatra.rubyforge.org"
@@ -1,81 +1,130 @@
1
1
  require File.dirname(__FILE__) + '/helper'
2
2
 
3
- describe 'Sinatra::Base' do
4
- it 'includes Rack::Utils' do
5
- assert Sinatra::Base.included_modules.include?(Rack::Utils)
3
+ describe 'Sinatra::Base subclasses' do
4
+
5
+ class TestApp < Sinatra::Base
6
+ get '/' do
7
+ 'Hello World'
8
+ end
9
+ end
10
+
11
+ it 'include Rack::Utils' do
12
+ assert TestApp.included_modules.include?(Rack::Utils)
6
13
  end
7
14
 
8
- it 'can be used as a Rack application' do
9
- mock_app {
10
- get '/' do
11
- 'Hello World'
12
- end
13
- }
14
- assert @app.respond_to?(:call)
15
+ it 'processes requests with #call' do
16
+ assert TestApp.respond_to?(:call)
15
17
 
16
- request = Rack::MockRequest.new(@app)
18
+ request = Rack::MockRequest.new(TestApp)
17
19
  response = request.get('/')
18
20
  assert response.ok?
19
21
  assert_equal 'Hello World', response.body
20
22
  end
21
23
 
22
- it 'can be used as Rack middleware' do
23
- app = lambda { |env| [200, {}, ['Goodbye World']] }
24
- mock_middleware =
25
- mock_app {
26
- get '/' do
27
- 'Hello World'
28
- end
29
- get '/goodbye' do
30
- @app.call(request.env)
31
- end
32
- }
33
- middleware = mock_middleware.new(app)
24
+ class TestApp < Sinatra::Base
25
+ get '/state' do
26
+ body = "Foo: #{@foo}"
27
+ @foo = 'discard'
28
+ body
29
+ end
30
+ end
31
+
32
+ it 'does not maintain state between requests' do
33
+ request = Rack::MockRequest.new(TestApp)
34
+ 2.times do
35
+ response = request.get('/state')
36
+ assert response.ok?
37
+ assert_equal 'Foo: ', response.body
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "Sinatra::Base as Rack middleware" do
43
+
44
+ app = lambda { |env|
45
+ [210, {'X-Downstream' => 'true'}, ['Hello from downstream']] }
46
+
47
+ class TestMiddleware < Sinatra::Base
48
+ end
49
+
50
+ it 'creates a middleware that responds to #call with .new' do
51
+ middleware = TestMiddleware.new(app)
52
+ assert middleware.respond_to?(:call)
53
+ end
54
+
55
+ it 'exposes the downstream app' do
56
+ middleware = TestMiddleware.new(app)
34
57
  assert_same app, middleware.app
58
+ end
59
+
60
+ class TestMiddleware < Sinatra::Base
61
+ get '/' do
62
+ 'Hello from middleware'
63
+ end
64
+ end
65
+
66
+ middleware = TestMiddleware.new(app)
67
+ request = Rack::MockRequest.new(middleware)
35
68
 
36
- request = Rack::MockRequest.new(middleware)
69
+ it 'intercepts requests' do
37
70
  response = request.get('/')
38
71
  assert response.ok?
39
- assert_equal 'Hello World', response.body
72
+ assert_equal 'Hello from middleware', response.body
73
+ end
40
74
 
41
- response = request.get('/goodbye')
42
- assert response.ok?
43
- assert_equal 'Goodbye World', response.body
75
+ it 'automatically forwards requests downstream when no matching route found' do
76
+ response = request.get('/missing')
77
+ assert_equal 210, response.status
78
+ assert_equal 'Hello from downstream', response.body
44
79
  end
45
80
 
46
- it 'can take multiple definitions of a route' do
47
- app = mock_app {
48
- user_agent(/Foo/)
49
- get '/foo' do
50
- 'foo'
51
- end
81
+ class TestMiddleware < Sinatra::Base
82
+ get '/low-level-forward' do
83
+ app.call(env)
84
+ end
85
+ end
52
86
 
53
- get '/foo' do
54
- 'not foo'
55
- end
56
- }
87
+ it 'can call the downstream app directly and return result' do
88
+ response = request.get('/low-level-forward')
89
+ assert_equal 210, response.status
90
+ assert_equal 'true', response['X-Downstream']
91
+ assert_equal 'Hello from downstream', response.body
92
+ end
57
93
 
58
- request = Rack::MockRequest.new(app)
59
- response = request.get('/foo', 'HTTP_USER_AGENT' => 'Foo')
60
- assert response.ok?
61
- assert_equal 'foo', response.body
94
+ class TestMiddleware < Sinatra::Base
95
+ get '/explicit-forward' do
96
+ response['X-Middleware'] = 'true'
97
+ res = forward
98
+ assert_nil res
99
+ assert_equal 210, response.status
100
+ assert_equal 'true', response['X-Downstream']
101
+ assert_equal ['Hello from downstream'], response.body
102
+ 'Hello after explicit forward'
103
+ end
104
+ end
62
105
 
63
- request = Rack::MockRequest.new(app)
64
- response = request.get('/foo')
65
- assert response.ok?
66
- assert_equal 'not foo', response.body
106
+ it 'forwards the request downstream and integrates the response into the current context' do
107
+ response = request.get('/explicit-forward')
108
+ assert_equal 210, response.status
109
+ assert_equal 'true', response['X-Downstream']
110
+ assert_equal 'Hello after explicit forward', response.body
111
+ assert_equal '28', response['Content-Length']
112
+ end
113
+
114
+ app_content_length = lambda {|env|
115
+ [200, {'Content-Length' => '16'}, 'From downstream!']}
116
+ class TestMiddlewareContentLength < Sinatra::Base
117
+ get '/forward' do
118
+ res = forward
119
+ 'From after explicit forward!'
120
+ end
67
121
  end
68
122
 
69
- it "makes redirecting back pretty" do
70
- app = mock_app {
71
- get '/foo' do
72
- redirect back
73
- end
74
- }
123
+ middleware_content_length = TestMiddlewareContentLength.new(app_content_length)
124
+ request_content_length = Rack::MockRequest.new(middleware_content_length)
75
125
 
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
126
+ it "sets content length for last response" do
127
+ response = request_content_length.get('/forward')
128
+ assert_equal '28', response['Content-Length']
80
129
  end
81
130
  end
@@ -47,4 +47,35 @@ describe "ERB Templates" do
47
47
  assert ok?
48
48
  assert_equal "ERB Layout!\nHello World\n", body
49
49
  end
50
+
51
+ it "renders erb with blocks" do
52
+ mock_app {
53
+ def container
54
+ @_out_buf << "THIS."
55
+ yield
56
+ @_out_buf << "SPARTA!"
57
+ end
58
+ def is; "IS." end
59
+ get '/' do
60
+ erb '<% container do %> <%= is %> <% end %>'
61
+ end
62
+ }
63
+ get '/'
64
+ assert ok?
65
+ assert_equal 'THIS. IS. SPARTA!', body
66
+ end
67
+
68
+ it "can be used in a nested fashion for partials and whatnot" do
69
+ mock_app {
70
+ template(:inner) { "<inner><%= 'hi' %></inner>" }
71
+ template(:outer) { "<outer><%= erb :inner %></outer>" }
72
+ get '/' do
73
+ erb :outer
74
+ end
75
+ }
76
+
77
+ get '/'
78
+ assert ok?
79
+ assert_equal '<outer><inner>hi</inner></outer>', body
80
+ end
50
81
  end
@@ -60,4 +60,25 @@ describe 'Registering extensions' do
60
60
  assert !Sinatra::Base.respond_to?(:baz)
61
61
  assert Sinatra::Default.respond_to?(:baz)
62
62
  end
63
+
64
+ module BizzleExtension
65
+ def bizzle
66
+ bizzle_option
67
+ end
68
+
69
+ def self.registered(base)
70
+ fail "base should be BizzleApp" unless base == BizzleApp
71
+ fail "base should have already extended BizzleExtension" unless base.respond_to?(:bizzle)
72
+ base.set :bizzle_option, 'bizzle!'
73
+ end
74
+ end
75
+
76
+ class BizzleApp < Sinatra::Base
77
+ end
78
+
79
+ it 'sends .registered to the extension module after extending the class' do
80
+ BizzleApp.register BizzleExtension
81
+ assert_equal 'bizzle!', BizzleApp.bizzle_option
82
+ assert_equal 'bizzle!', BizzleApp.bizzle
83
+ end
63
84
  end
@@ -8,21 +8,40 @@ end
8
8
  libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
9
9
  $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
10
10
 
11
- require 'sinatra/base'
12
- require 'sinatra/test/unit'
11
+ require 'test/unit'
12
+ require 'sinatra/test'
13
+
14
+ class Sinatra::Base
15
+ # Allow assertions in request context
16
+ include Test::Unit::Assertions
17
+ end
18
+
19
+ class Test::Unit::TestCase
20
+ include Sinatra::Test
21
+
22
+ def setup
23
+ Sinatra::Default.set :environment, :test
24
+ end
13
25
 
14
- module Sinatra::Test
15
26
  # Sets up a Sinatra::Base subclass defined with the block
16
27
  # given. Used in setup or individual spec methods to establish
17
28
  # the application.
18
29
  def mock_app(base=Sinatra::Base, &block)
19
30
  @app = Sinatra.new(base, &block)
20
31
  end
21
- end
22
32
 
23
- class Sinatra::Base
24
- # Allow assertions in request context
25
- include Test::Unit::Assertions
33
+ def restore_default_options
34
+ Sinatra::Default.set(
35
+ :environment => :development,
36
+ :raise_errors => Proc.new { test? },
37
+ :dump_errors => true,
38
+ :sessions => false,
39
+ :logging => Proc.new { ! test? },
40
+ :methodoverride => true,
41
+ :static => true,
42
+ :run => Proc.new { ! test? }
43
+ )
44
+ end
26
45
  end
27
46
 
28
47
  ##
@@ -31,7 +50,7 @@ end
31
50
  # chris@ozmm.org
32
51
  #
33
52
  def describe(*args, &block)
34
- return super unless (name = args.first) && block
53
+ return super unless (name = args.first.capitalize) && block
35
54
  name = "#{name.gsub(/\W/, '')}Test"
36
55
  Object.send :const_set, name, Class.new(Test::Unit::TestCase)
37
56
  klass = Object.const_get(name)
@@ -44,6 +63,17 @@ def describe(*args, &block)
44
63
  def self.after(&block) define_method(:teardown, &block) end
45
64
  end
46
65
  klass.class_eval &block
66
+ klass
67
+ end
68
+
69
+ def describe_option(name, &block)
70
+ klass = describe("Option #{name}", &block)
71
+ klass.before do
72
+ restore_default_options
73
+ @base = Sinatra.new
74
+ @default = Class.new(Sinatra::Default)
75
+ end
76
+ klass
47
77
  end
48
78
 
49
79
  # Do not output warnings for the duration of the block.