Permalink
Browse files

add reimplementation of sinatra-extension

  • Loading branch information...
1 parent 0895ddf commit 9a27404a501ad1dd7d0998f0ba15de9207ba589e @rkh rkh committed Mar 25, 2011
Showing with 92 additions and 4 deletions.
  1. +1 −0 lib/sinatra/contrib.rb
  2. +50 −0 lib/sinatra/extension.rb
  3. +8 −1 lib/sinatra/test_helpers.rb
  4. +0 −3 spec/config_file_spec.rb
  5. +33 −0 spec/extension_spec.rb
@@ -21,6 +21,7 @@ module Custom
##
# Stuff that aren't Sinatra extensions, technically.
+ autoload :Extension
autoload :TestHelpers
end
@@ -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
@@ -21,13 +21,20 @@ def default_env
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)
@@ -2,11 +2,8 @@
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
@@ -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

0 comments on commit 9a27404

Please sign in to comment.