* Splat works

* Filter by agent
This commit is contained in:
Blake Mizerany 2008-01-11 17:01:00 -08:00
parent 95287a1b55
commit bf896df252
3 changed files with 53 additions and 16 deletions

View File

@ -70,22 +70,29 @@ module Sinatra
URI_CHAR = '[^/?:,&#\.]'.freeze unless defined?(URI_CHAR)
PARAM = /:(#{URI_CHAR}+)/.freeze unless defined?(PARAM)
SPLAT = /(.*?)/
attr_reader :path, :block, :param_keys, :pattern, :options
attr_reader :path, :block, :param_keys, :pattern
def initialize(path, &b)
def initialize(path, options = {}, &b)
@path = path
@block = b
@param_keys = []
@options = options
regex = @path.to_s.gsub(PARAM) do
@param_keys << $1.intern
"(#{URI_CHAR}+)"
end
regex.gsub!('*', SPLAT.to_s)
@pattern = /^#{regex}$/
end
def invoke(env)
return unless pattern =~ env['PATH_INFO'].squeeze('/')
if options[:agent]
return unless env['HTTP_USER_AGENT'] =~ options[:agent]
end
params = param_keys.zip($~.captures.map(&:from_param)).to_hash
Result.new(block, params, 200)
end
@ -273,8 +280,8 @@ module Sinatra
@layouts = Hash.new
end
def define_event(method, path, &b)
events[method] << event = Event.new(path, &b)
def define_event(method, path, options = {}, &b)
events[method] << event = Event.new(path, options, &b)
event
end
@ -282,7 +289,7 @@ module Sinatra
layouts[name] = b
end
def define_error(code, &b)
def define_error(code, options = {}, &b)
events[:errors][code] = Error.new(code, &b)
end
@ -347,28 +354,28 @@ module Sinatra
end
def get(path, &b)
Sinatra.application.define_event(:get, path, &b)
def get(path, options ={}, &b)
Sinatra.application.define_event(:get, path, options, &b)
end
def post(path, &b)
Sinatra.application.define_event(:post, path, &b)
def post(path, options ={}, &b)
Sinatra.application.define_event(:post, path, options, &b)
end
def put(path, &b)
Sinatra.application.define_event(:put, path, &b)
def put(path, options ={}, &b)
Sinatra.application.define_event(:put, path, options, &b)
end
def delete(path, &b)
Sinatra.application.define_event(:delete, path, &b)
def delete(path, options ={}, &b)
Sinatra.application.define_event(:delete, path, options, &b)
end
def helpers(&b)
Sinatra::EventContext.class_eval(&b)
end
def error(code, &b)
Sinatra.application.define_error(code, &b)
def error(code, options = {}, &b)
Sinatra.application.define_error(code, options, &b)
end
def layout(name = :layout, &b)

View File

@ -129,6 +129,30 @@ context "Events in an app" do
result.should.be.ok
result.body.should.equal 'foobaz'
end
specify "can filters by agent" do
@app.define_event(:get, '/', :agent => /Windows/) do
request.env['HTTP_USER_AGENT']
end
Rack::MockRequest::DEFAULT_ENV.merge!('HTTP_USER_AGENT' => 'Windows')
request = Rack::MockRequest.new(@app)
result = request.get('/')
result.should.be.ok
result.body.should.equal 'Windows'
Rack::MockRequest::DEFAULT_ENV.merge!('HTTP_USER_AGENT' => 'Mac')
request = Rack::MockRequest.new(@app)
result = request.get('/')
result.should.not.be.ok
Rack::MockRequest::DEFAULT_ENV.delete('HTTP_USER_AGENT')
end
end

View File

@ -40,5 +40,11 @@ context "Simple Events" do
result = invoke_simple('/x/y', '/x//y')
result.should.not.be.nil
end
specify "understands splat" do
invoke_simple('/foo/*', '/foo/bar').should.not.be.nil
invoke_simple('/foo/*', '/foo/bar/baz').should.not.be.nil
invoke_simple('/foo/*', '/foo/baz').should.not.be.nil
end
end