add reimplementation of sinatra-extension

This commit is contained in:
Konstantin Haase 2011-03-26 00:13:26 +01:00
parent e6f15a2888
commit 18e379f1cf
5 changed files with 92 additions and 4 deletions

View File

@ -21,6 +21,7 @@ module Sinatra
##
# Stuff that aren't Sinatra extensions, technically.
autoload :Extension
autoload :TestHelpers
end

View File

@ -0,0 +1,50 @@
require 'sinatra/base'
require 'backports/basic_object' unless defined? BasicObject
module Sinatra
module Extension
def self.new(&block)
ext = Module.new.extend(self)
ext.class_eval(&block)
ext
end
def settings
self
end
def configure(*args, &block)
record(:configure, *args) { |c| c.instance_exec(c, &block) }
end
def registered(base = nil, &block)
base ? replay(base) : record(:class_eval, &block)
end
private
def record(method, *args, &block)
recorded_methods << [method, args, block]
end
def replay(object)
recorded_methods.each { |m, a, b| object.send(m, *a, &b) }
end
def recorded_methods
@recorded_methods ||= []
end
def method_missing(method, *args, &block)
return super unless Sinatra::Base.respond_to? method
record(method, *args, &block)
DontCall.new(method)
end
class DontCall < BasicObject
def initialize(method) @method = method end
def method_missing(*) fail "not supposed to use result of #@method!" end
def inspect; "#<#{self.class}: #{@method}>" end
end
end
end

View File

@ -21,13 +21,20 @@ module Sinatra
include Rack::Test::Methods
extend Forwardable
attr_accessor :settings
def_delegators :last_response, :body, :headers, :status, :errors
def_delegators :app, :configure, :set, :enable, :disable, :use, :helpers, :register
def_delegators :current_session, :env_for
def mock_app(base = Sinatra::Base, &block)
@app = Sinatra.new(base, &block)
inner = nil
@app = Sinatra.new(base) do
inner = self
class_eval(&block)
end
@settings = inner
app
end
def app=(base)

View File

@ -2,11 +2,8 @@ require 'backports'
require_relative 'spec_helper'
describe Sinatra::ConfigFile do
attr_accessor :settings
def config_file(*args, &block)
test = self
mock_app do
test.settings = settings
register Sinatra::ConfigFile
set :root, File.expand_path('../config_file', __FILE__)
instance_eval(&block) if block

View File

@ -0,0 +1,33 @@
require 'backports'
require_relative 'spec_helper'
describe Sinatra::Extension do
module ExampleExtension
extend Sinatra::Extension
set :foo, :bar
settings.set :bar, :blah
configure :test, :production do
set :reload_stuff, false
end
configure :development do
set :reload_stuff, true
end
get '/' do
"from extension, yay"
end
end
before { mock_app { register ExampleExtension }}
it('allows using set') { settings.foo.should == :bar }
it('implements configure') { settings.reload_stuff.should be_false }
it 'allows defing routes' do
get('/').should be_ok
body.should == "from extension, yay"
end
end