Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

all but one example of the path pattern compilation tests work

  • Loading branch information...
commit 3a8f40f684f2f477ac322345a5d5e2e578461df9 1 parent e2a020c
@floere authored
Showing with 31 additions and 18 deletions.
  1. +12 −4 lib/sinatra/base.rb
  2. +19 −14 test/compile_test.rb
View
16 lib/sinatra/base.rb
@@ -1,4 +1,4 @@
-# external dependencies
+ # external dependencies
require 'rack'
require 'tilt'
require "rack/protection"
@@ -1302,14 +1302,18 @@ def compile!(verb, path, block, options = {})
def compile(path)
keys = []
if path.respond_to? :to_str
- pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) { |c| encoded(c) }
+ pad = []
+ pattern = path.to_str.gsub(/[^\?\%\\\/\:\*\w]/) do |c|
+ pad += escaped(c) if c.match(/[\.@]/)
+ encoded(c)
+ end
pattern.gsub!(/((:\w+)|\*)/) do |match|
if match == "*"
keys << 'splat'
"(.*?)"
else
keys << $2[1..-1]
- "([^/?#]+)"
+ "([^#{pad.join}/?#]+)"
end
end
[/^#{pattern}$/, keys]
@@ -1328,10 +1332,14 @@ def compile(path)
def encoded(char)
enc = URI.escape(char)
- enc = "(?:#{Regexp.escape enc}|#{URI.escape char, /./})" if enc == char
+ enc = "(?:#{escaped(char, enc).join('|')})" if enc == char
enc = "(?:#{enc}|#{encoded('+')})" if char == " "
enc
end
+
+ def escaped(char, enc = URI.escape(char))
+ [Regexp.escape(enc), URI.escape(char, /./)]
+ end
public
# Makes the methods defined in the block and in the Modules given
View
33 test/compile_test.rb
@@ -26,11 +26,6 @@ class CompileTest < Test::Unit::TestCase
["/*" , %r{^/(.*?)$} , "/foo/bar" , ["foo/bar"] ],
["/:foo/*" , %r{^/([^/?#]+)/(.*?)$} , "/foo/bar/baz" , ["foo", "bar/baz"] ],
["/:foo/:bar" , %r{^/([^/?#]+)/([^/?#]+)$} , "/user@example.com/name" , ["user@example.com", "name"] ],
- ["/:file.:ext" , %r{^/([^/?#]+)(?:\.|%2E)([^/?#]+)$} , "/pony.jpg" , ["pony", "jpg"] ],
- ["/:file.:ext" , %r{^/([^/?#]+)(?:\.|%2E)([^/?#]+)$} , "/pony%2Ejpg" , ["pony", "jpg"] ],
- ["/:file.:ext" , %r{^/([^/?#]+)(?:\.|%2E)([^/?#]+)$} , "/.jpg" , nil ],
- ["/test.bar" , %r{^/test(?:\.|%2E)bar$} , "/test.bar" , [] ],
- ["/test.bar" , %r{^/test(?:\.|%2E)bar$} , "/test0bar" , nil ],
["/test$/" , %r{^/test(?:\$|%24)/$} , "/test$/" , [] ],
["/te+st/" , %r{^/te(?:\+|%2B)st/$} , "/te+st/" , [] ],
["/te+st/" , %r{^/te(?:\+|%2B)st/$} , "/test/" , nil ],
@@ -43,21 +38,31 @@ class CompileTest < Test::Unit::TestCase
["/:foo/*" , %r{^/([^/?#]+)/(.*?)$} , "/hello%20world/how%20are%20you" , ["hello%20world", "how%20are%20you"]],
["/*/foo/*/*" , %r{^/(.*?)/foo/(.*?)/(.*?)$} , "/bar/foo/bling/baz/boom" , ["bar", "bling", "baz/boom"] ],
["/*/foo/*/*" , %r{^/(.*?)/foo/(.*?)/(.*?)$} , "/bar/foo/baz" , nil ],
- ["/:name.?:format?" , %r{^/([^/?#]+)(?:\.|%2E)?([^/?#]+)?$} , "/foo" , ["foo", nil] ],
- ["/:name.?:format?" , %r{^/([^/?#]+)(?:\.|%2E)?([^/?#]+)?$} , "/.bar" , [".bar", nil] ],
- ["/:name.?:format?" , %r{^/([^/?#]+)(?:\.|%2E)?([^/?#]+)?$} , "/foo.bar" , ["foo", "bar"] ],
- ["/:name.?:format?" , %r{^/([^/?#]+)(?:\.|%2E)?([^/?#]+)?$} , "/foo%2Ebar" , ["foo", "bar"] ],
- ["/:user@?:host?" , %r{^/([^/?#]+)(?:@|%40)?([^/?#]+)?$} , "/foo@bar" , ["foo", "bar"] ],
- ["/:user@?:host?" , %r{^/([^/?#]+)(?:@|%40)?([^/?#]+)?$} , "/foo.foo@bar" , ["foo.foo", "bar"] ],
- ["/:user@?:host?" , %r{^/([^/?#]+)(?:@|%40)?([^/?#]+)?$} , "/foo@bar.bar" , ["foo", "bar.bar"] ],
+ ["/test.bar" , %r{^/test(?:\.|%2E)bar$} , "/test.bar" , [] ],
+ ["/test.bar" , %r{^/test(?:\.|%2E)bar$} , "/test0bar" , nil ],
+ ["/:file.:ext" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)([^\.%2E/?#]+)$} , "/pony.jpg" , ["pony", "jpg"] ],
+ ["/:file.:ext" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)([^\.%2E/?#]+)$} , "/pony%2Ejpg" , ["pony", "jpg"] ],
+ ["/:file.:ext" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)([^\.%2E/?#]+)$} , "/.jpg" , nil ],
+ ["/:name.?:format?" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)?([^\.%2E/?#]+)?$} , "/foo" , ["foo", nil] ],
+ ["/:name.?:format?" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)?([^\.%2E/?#]+)?$} , "/.bar" , [".bar", nil] ],
+ ["/:name.?:format?" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)?([^\.%2E/?#]+)?$} , "/foo.bar" , ["foo", "bar"] ],
+ ["/:name.?:format?" , %r{^/([^\.%2E/?#]+)(?:\.|%2E)?([^\.%2E/?#]+)?$} , "/foo%2Ebar" , ["foo", "bar"] ],
+ ["/:user@?:host?" , %r{^/([^@%40/?#]+)(?:@|%40)?([^@%40/?#]+)?$} , "/foo@bar" , ["foo", "bar"] ],
+ ["/:user@?:host?" , %r{^/([^@%40/?#]+)(?:@|%40)?([^@%40/?#]+)?$} , "/foo.foo@bar" , ["foo.foo", "bar"] ],
+ ["/:user@?:host?" , %r{^/([^@%40/?#]+)(?:@|%40)?([^@%40/?#]+)?$} , "/foo@bar.bar" , ["foo", "bar.bar"] ],
].each do |pattern, regexp, example, expected|
app = nil
it "generates #{regexp.source} from #{pattern}, with #{example} succeeding" do
app ||= mock_app {}
compiled, keys = app.send(:compile, pattern)
- assert_equal regexp.source, compiled.source
+
match = compiled.match(example)
- match ? assert_equal(expected, match.captures.to_a) : assert_nil(expected)
+ match ? assert_equal(expected, match.captures.to_a) : assert_equal(expected, match)
+
+ # Compare the regexp last, to see that the captures work,
+ # but the regexp might not the expected one.
+ #
+ assert_equal regexp, compiled
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.