Permalink
Browse files

Add Rack::Callbacks. Example :

application = Rack::Callbacks.new do
  before Filter1, arguments
  before Filter1

  run RackApplication.new

  after Hourkeeping
end

Rack::Builder.new do
  run application
end
  • Loading branch information...
1 parent 50fd7a3 commit ec0fb58ee4782b29483cba58833d1a67ac33252e @lifo lifo committed Jan 14, 2009
Showing with 83 additions and 0 deletions.
  1. +2 −0 README.rdoc
  2. +1 −0 lib/rack/contrib.rb
  3. +36 −0 lib/rack/contrib/callbacks.rb
  4. +44 −0 test/spec_rack_callbacks.rb
View
2 README.rdoc
@@ -23,6 +23,8 @@ interface:
from file.
* Rack::TimeZone - Detects the clients timezone using JavaScript and sets
a variable in Rack's environment with the offset from UTC.
+* Rack::Evil - Lets the rack application return a response to the client from any place.
+* Rack::Callbacks - Implements DLS for pure before/after filter like Middlewares.
=== Use
View
1 lib/rack/contrib.rb
@@ -19,4 +19,5 @@ def self.release
autoload :Sendfile, "rack/contrib/sendfile"
autoload :TimeZone, "rack/contrib/time_zone"
autoload :Evil, "rack/contrib/evil"
+ autoload :Callbacks, "rack/contrib/callbacks"
end
View
36 lib/rack/contrib/callbacks.rb
@@ -0,0 +1,36 @@
+module Rack
+ class Callbacks
+ def initialize(&block)
+ @before = []
+ @after = []
+ instance_eval(&block) if block_given?
+ end
+
+ def before(middleware, *args, &block)
+ if block_given?
+ @before << middleware.new(*args, &block)
+ else
+ @before << middleware.new(*args)
+ end
+ end
+
+ def after(middleware, *args, &block)
+ if block_given?
+ @after << middleware.new(*args, &block)
+ else
+ @after << middleware.new(*args)
+ end
+ end
+
+ def run(app)
+ @app = app
+ end
+
+ def call(env)
+ @before.each {|c| c.call(env) }
+ response = @app.call(env)
+ @after.each {|c| c.call(env) }
+ response
+ end
+ end
+end
View
44 test/spec_rack_callbacks.rb
@@ -0,0 +1,44 @@
+require 'rack/mock'
+
+class Flame
+ def call(env)
+ env['flame'] = 'F Lifo..'
+ end
+end
+
+class Pacify
+ def initialize(with)
+ @with = with
+ end
+
+ def call(env)
+ env['peace'] = @with
+ end
+end
+
+class Finale
+ def call(env)
+ $hax_logger = 'lol'
+ end
+end
+
+context "Rack::Callbacks" do
+ specify "works for love and small stack trace" do
+ callback_app = Rack::Callbacks.new do
+ before Flame
+ before Pacify, "with love"
+
+ run lambda {|env| [200, {}, env['flame'] + env['peace']] }
+
+ after Finale
+ end
+
+ app = Rack::Builder.new do
+ run callback_app
+ end.to_app
+
+ response = Rack::MockRequest.new(app).get("/")
+ response.body.to_s.should.equal 'F Lifo..with love'
+ $hax_logger.should.equal 'lol'
+ end
+end

0 comments on commit ec0fb58

Please sign in to comment.