Skip to content

Commit

Permalink
add Sinatra::Delegator.target and actually test delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
rkh committed Mar 21, 2011
1 parent 782f7df commit a6cf359
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGES
Expand Up @@ -10,6 +10,10 @@
* URIs passed to the `url` helper or `redirect` may now use any schema to be
identified as absolute URIs, not only `http` or `https`. (Konstantin Haase)

* It is now possible to use a different target class for the top level DLS (aka
classic style) than `Sinatra::Application` by setting `Delegator.target`.
This was mainly introduced to ease testing. (Konstantin Haase)

= 1.2.1 / 2011-03-17

* Use a generated session secret when using `enable :sessions`. (Konstantin
Expand Down
8 changes: 7 additions & 1 deletion lib/sinatra/base.rb
Expand Up @@ -1442,7 +1442,7 @@ def self.delegate(*methods)
methods.each do |method_name|
eval <<-RUBY, binding, '(__DELEGATE__)', 1
def #{method_name}(*args, &b)
::Sinatra::Application.send(#{method_name.inspect}, *args, &b)
::Sinatra::Delegator.target.send(#{method_name.inspect}, *args, &b)
end
private #{method_name.inspect}
RUBY
Expand All @@ -1453,6 +1453,12 @@ def #{method_name}(*args, &b)
:before, :after, :error, :not_found, :configure, :set, :mime_type,
:enable, :disable, :use, :development?, :test?, :production?,
:helpers, :settings

class << self
attr_accessor :target
end

self.target = Application
end

# Create a new Sinatra application. The block is evaluated in the new app's
Expand Down
115 changes: 115 additions & 0 deletions test/delegator_test.rb
@@ -0,0 +1,115 @@
class DelegatorTest < Test::Unit::TestCase
class Mirror
attr_reader :last_call
def method_missing(*a, &b)
@last_call = [*a.map(&:to_s)]
@last_call << b if b
end
end

def self.delegates(name)
it "delegates #{name}" do
m = mirror { send name }
assert_equal m.last_call, [name.to_s]
end

it "delegates #{name} with arguments" do
m = mirror { send name, "foo", "bar" }
assert_equal m.last_call, [name.to_s, "foo", "bar"]
end

it "delegates #{name} with block" do
block = proc { }
m = mirror { send(name, &block) }
assert_equal m.last_call, [name.to_s, block]
end
end

setup do
@target_was = Sinatra::Delegator.target
end

def teardown
Sinatra::Delegator.target = @target_was
end

def delegation_app(&block)
mock_app { Sinatra::Delegator.target = self }
delegate(&block)
end

def mirror(&block)
mirror = Mirror.new
Sinatra::Delegator.target = mirror
delegate(&block)
end

def delegate(&block)
assert Sinatra::Delegator.target != Sinatra::Application
Object.new.extend(Sinatra::Delegator).instance_eval(&block)
Sinatra::Delegator.target
end

def target
Sinatra::Delegator.target
end

it 'defaults to Sinatra::Application as target' do
assert_equal Sinatra::Delegator.target, Sinatra::Application
end

%w[get put post delete options patch].each do |verb|
it "delegates #{verb} correctly" do
delegation_app do
send verb, '/hello' do
'Hello World'
end
end

request = Rack::MockRequest.new(@app)
response = request.request(verb.upcase, '/hello', {})
assert response.ok?
assert_equal 'Hello World', response.body
end
end

it "delegates head correctly" do
delegation_app do
head '/hello' do
response['X-Hello'] = 'World!'
'remove me'
end
end

request = Rack::MockRequest.new(@app)
response = request.request('HEAD', '/hello', {})
assert response.ok?
assert_equal 'World!', response['X-Hello']
assert_equal '', response.body
end

delegates 'get'
delegates 'patch'
delegates 'put'
delegates 'post'
delegates 'delete'
delegates 'head'
delegates 'options'
delegates 'template'
delegates 'layout'
delegates 'before'
delegates 'after'
delegates 'error'
delegates 'not_found'
delegates 'configure'
delegates 'set'
delegates 'mime_type'
delegates 'enable'
delegates 'disable'
delegates 'use'
delegates 'development?'
delegates 'test?'
delegates 'production?'
delegates 'helpers'
delegates 'settings'
end

0 comments on commit a6cf359

Please sign in to comment.