* Splat works
authorBlake Mizerany <blake@blake.local>
Sat, 12 Jan 2008 01:01:00 +0000 (11 17:01 -0800)
committerBlake Mizerany <blake@blake.local>
Sat, 12 Jan 2008 01:01:00 +0000 (11 17:01 -0800)
* Filter by agent

lib/sinatra.rb
test/application_test.rb
test/events_test.rb

index 5f5004b..00f5f8e 100644 (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)
index 6ccd130..a2ab27a 100644 (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
 
index 6b23b11..6a481da 100644 (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