Skip to content

Commit

Permalink
Adds a after filter
Browse files Browse the repository at this point in the history
  • Loading branch information
jschementi committed Dec 22, 2008
1 parent 6e40443 commit e87b0ba
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
6 changes: 6 additions & 0 deletions README.rdoc
Expand Up @@ -211,6 +211,12 @@ These are run in Sinatra::EventContext before every event.
.. this code will run before each event ..
end

These are run in Sinatra::EventContext after every event.

after do
.. this code will run after each event ..
end

== Halt!

To immediately stop a request during a before filter or event use:
Expand Down
18 changes: 14 additions & 4 deletions lib/sinatra.rb
Expand Up @@ -872,7 +872,7 @@ class Application
# Hash of template name mappings.
attr_reader :templates

# Hash of filters with event name keys (:before) and arrays of
# Hash of filters with event name keys (:before, :after) and arrays of
# handlers as values.
attr_reader :filters

Expand All @@ -888,7 +888,7 @@ class Application
# top-level the method is forwarded to the default application
# (Sinatra::application).
FORWARD_METHODS = %w[
get put post delete head template layout before error not_found
get put post delete head template layout before after error not_found
configures configure set set_options set_option enable disable use
development? test? production?
]
Expand Down Expand Up @@ -1123,6 +1123,7 @@ def not_found(options={}, &b)

# Define a request filter. When <tt>type</tt> is <tt>:before</tt>, execute the
# block in the context of each request before matching event handlers.
# <tt>:after</tt> executes after each request handler executes.
def filter(type, &b)
filters[type] << b
end
Expand All @@ -1133,6 +1134,12 @@ def before(&b)
filter :before, &b
end

# Invoke the block in the context of each request after invoking
# matching event handler.
def after(&b)
filter :after, &b
end

# True when environment is :development.
def development? ; options.env == :development ; end

Expand Down Expand Up @@ -1236,7 +1243,8 @@ def call(env)
# 3. Create new EventContext to house event handler evaluation.
# 4. Invoke each #before filter in context of EventContext object.
# 5. Invoke event handler in context of EventContext object.
# 6. Return response to Rack.
# 6. Invoke each #after filter in the context of EventContext object.
# 7. Return response to Rack.
#
# See the Rack specification for detailed information on the
# +env+ argument and return value.
Expand All @@ -1251,7 +1259,9 @@ def dispatch(env)
context.route_params = result.params
context.response.status = result.status
context.reset!
[:complete, context.instance_eval(&result.block)]
r = context.instance_eval(&result.block)
filters[:after].each { |f| context.instance_eval(&f) }
[:complete, r]
end
body = returned.to_result(context)
rescue => e
Expand Down
19 changes: 19 additions & 0 deletions test/filter_test.rb
Expand Up @@ -28,3 +28,22 @@
end

end

context "after filters" do

setup do
Sinatra.application = nil
@app = Sinatra.application
end

specify "should be executed after the request" do
invoked = 0
@app.before { invoked = 2 }
@app.get('/') { invoked += 2 }
@app.after { invoked *= 2 }
get_it '/'
should.be.ok
invoked.should.be == 8
end

end

0 comments on commit e87b0ba

Please sign in to comment.