Permalink
Browse files

Specs, documentation and fixes for splat'n routes

  • Loading branch information...
1 parent 1987e55 commit 9c85e99c995c742671ba970defac59e3dfcb7bb5 @vic vic committed with Blake Mizerany Apr 25, 2008
Showing with 65 additions and 9 deletions.
  1. +8 −2 README.rdoc
  2. +17 −7 lib/sinatra.rb
  3. +40 −0 test/app_test.rb
View
@@ -57,8 +57,14 @@ With params
Splat'n
- get '/message/*' do
- # matches /message/1/2/3/4/5
+ get '/say/*/to/*' do
+ # matches /say/hello/to/world
+ params["splat"] # => ["hello", "world"]
+ end
+
+ get '/download/*.*' do
+ # matches /download/path/to/file.xml
+ params["splat"] # => ["path/to/file", "xml"]
end
Get an agent!
View
@@ -164,7 +164,7 @@ def run
class Event
URI_CHAR = '[^/?:,&#\.]'.freeze unless defined?(URI_CHAR)
- PARAM = /:(#{URI_CHAR}+)/.freeze unless defined?(PARAM)
+ PARAM = /(:(#{URI_CHAR}+)|\*)/.freeze unless defined?(PARAM)
SPLAT = /(.*?)/
attr_reader :path, :block, :param_keys, :pattern, :options
@@ -173,13 +173,18 @@ def initialize(path, options = {}, &b)
@block = b
@param_keys = []
@options = options
- regex = @path.to_s.gsub(PARAM) do
- @param_keys << $1
- "(#{URI_CHAR}+)"
+ splats = 0
+ regex = @path.to_s.gsub(PARAM) do |match|
+ if match == "*"
+ @param_keys << "_splat_#{splats}"
+ splats += 1
+ SPLAT.to_s
+ else
+ @param_keys << $2
+ "(#{URI_CHAR}+)"
+ end
end
-
- regex.gsub!('*', SPLAT.to_s)
-
+
@pattern = /^#{regex}$/
end
@@ -194,6 +199,11 @@ def invoke(request)
end
return unless pattern =~ request.path_info.squeeze('/')
params.merge!(param_keys.zip($~.captures.map(&:from_param)).to_hash)
+ splats = params.select { |k, v| k =~ /^_splat_\d+$/ }.sort.map(&:last)
+ unless splats.empty?
+ params.delete_if { |k, v| k =~ /^_splat_\d+$/ }
+ params["splat"] = splats
+ end
Result.new(block, params, 200)
end
View
@@ -27,6 +27,46 @@
body.should.equal 'Hello Blake'
end
+
+ specify "handles splats" do
+ get '/hi/*' do
+ params["splat"].kind_of?(Array).should.equal true
+ params["splat"].first
+ end
+
+ get_it '/hi/Blake'
+
+ should.be.ok
+ body.should.equal 'Blake'
+ end
+
+ specify "handles multiple splats" do
+ get '/say/*/to/*' do
+ params["splat"].join(' ')
+ end
+
+ get_it '/say/hello/to/world'
+
+ should.be.ok
+ body.should.equal 'hello world'
+ end
+
+ specify "allow empty splats" do
+ get '/say/*/to*/*' do
+ params["splat"].join(' ')
+ end
+
+ get_it '/say/hello/to/world'
+
+ should.be.ok
+ body.should.equal 'hello world' # second splat is empty
+
+ get_it '/say/hello/tomy/world'
+
+ should.be.ok
+ body.should.equal 'hello my world'
+ end
+
specify "gives access to underlying response header Hash" do
get '/' do
header['X-Test'] = 'Is this thing on?'

0 comments on commit 9c85e99

Please sign in to comment.