Added Sinatra.register and Sinatra.helpers

Sinatra.register:

* This will extend the DSL in Sinatra::Default (and subclasses) with
  the modules passed.

* All public methods in the extensions are added to Sinatra::Delegator
  when extending Sinatra::Default or it's subclasses.

* Sinatra::Base.register is available to add extensions to arbitrary
  classes (but they don't add methods to Delegator).

* You can pass a block with extensions which will get added as an
  anonymous block (same semantics of Sinatra::Base.helpers)

Sinatra.helpers:

* Will forward the modules passed to Default.helpers.

* Small change in semantics: passing a block to helpers will no longer
  class_eval the block, but will instead turn it into an anonymous
  module. This pushes it into the inheritance chain "normally" and
  allows us to call super to reach the original method if redefined.
This commit is contained in:
Nicolas Sanguinetti 2009-01-28 14:30:10 -02:00 committed by bmizerany
parent 8019e117f8
commit 57183bc004
2 changed files with 83 additions and 3 deletions

View File

@ -673,9 +673,14 @@ module Sinatra
end
public
def helpers(*modules, &block)
include *modules unless modules.empty?
class_eval(&block) if block
def helpers(*extensions, &block)
extensions << Module.new(&block) if block
include *extensions
end
def register(*extensions, &block)
extensions << Module.new(&block) if block
extend *extensions
end
def development? ; environment == :development ; end
@ -891,6 +896,12 @@ module Sinatra
@reloading = false
end
def self.register(*extensions, &block)
added_methods = extensions.map {|m| m.public_instance_methods }.flatten
Delegator.delegate *added_methods
super(*extensions, &block)
end
@@mutex = Mutex.new
def self.synchronize(&block)
if lock?
@ -927,4 +938,12 @@ module Sinatra
base.send :class_eval, &block if block_given?
base
end
def self.register(*extensions, &block)
Default.register(*extensions, &block)
end
def self.helpers(*extensions, &block)
Default.helpers(*extensions, &block)
end
end

61
test/extensions_test.rb Normal file
View File

@ -0,0 +1,61 @@
require File.dirname(__FILE__) + '/helper'
describe 'Registering extensions' do
module FooExtensions
def foo
end
private
def im_hiding_in_ur_foos
end
end
module BarExtensions
def bar
end
end
module BazExtensions
def baz
end
end
module QuuxExtensions
def quux
end
end
it 'will add the methods to the DSL for the class in which you register them and its subclasses' do
Sinatra::Base.register FooExtensions
assert Sinatra::Base.respond_to?(:foo)
Sinatra::Default.register BarExtensions
assert Sinatra::Default.respond_to?(:bar)
assert Sinatra::Default.respond_to?(:foo)
assert !Sinatra::Base.respond_to?(:bar)
end
it 'allows extending by passing a block' do
Sinatra::Base.register {
def im_in_ur_anonymous_module; end
}
assert Sinatra::Base.respond_to?(:im_in_ur_anonymous_module)
end
it 'will make sure any public methods added via Default#register are delegated to Sinatra::Delegator' do
Sinatra::Default.register FooExtensions
assert Sinatra::Delegator.private_instance_methods.include?("foo")
assert !Sinatra::Delegator.private_instance_methods.include?("im_hiding_in_ur_foos")
end
it 'will not delegate methods on Base#register' do
Sinatra::Base.register QuuxExtensions
assert !Sinatra::Delegator.private_instance_methods.include?("quux")
end
it 'will extend the Sinatra::Default application by default' do
Sinatra.register BazExtensions
assert !Sinatra::Base.respond_to?(:baz)
assert Sinatra::Default.respond_to?(:baz)
end
end