Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix regex route generation

  • Loading branch information...
commit 08bfa9cbc730587dce72169f8c6e6031bd9dce27 1 parent 7d3ec45
@joshbuddy authored
View
1  lib/http_router.rb
@@ -9,6 +9,7 @@
require 'http_router/route'
require 'http_router/rack'
require 'http_router/regex_route'
+require 'http_router/util'
class HttpRouter
View
34 lib/http_router/node/path.rb
@@ -6,7 +6,7 @@ class Path < Node
def initialize(router, parent, route, path, param_names = [])
@route, @original_path, @param_names, @dynamic = route, path, param_names, !param_names.empty?
raise AmbiguousVariableException, "You have duplicate variable name present: #{param_names.join(', ')}" if param_names.uniq.size != param_names.size
- process_path_for_generation(@original_path) if @original_path.respond_to?(:split)
+ Util.add_path_generation(self, route, @original_path) if @original_path.respond_to?(:split)
super router, parent
root.uncompile
end
@@ -57,38 +57,6 @@ def usable?(other)
def raw_url(args, options)
raise InvalidRouteException
end
-
- def process_path_for_generation(path, path_validation_regex = nil)
- @path_validation_regex = path_validation_regex
- regex_parts = path.split(/([:\*][a-zA-Z0-9_]+)/)
- regex, code = '', ''
- regex_parts.each_with_index do |part, index|
- case part[0]
- when ?:, ?*
- if index != 0 && regex_parts[index - 1][-1] == ?\\
- regex << Regexp.quote(part)
- code << part
- else
- regex << (route.matches_with[part[1, part.size].to_sym] || '.*?').to_s
- code << "\#{args.shift || (options && options.delete(:#{part[1, part.size]})) || return}"
- end
- else
- regex << Regexp.quote(part)
- code << part
- end
- end
- @path_validation_regex ||= Regexp.new("^#{regex}$") if dynamic?
- if @path_validation_regex
- instance_eval <<-EOT, __FILE__, __LINE__ + 1
- def raw_url(args, options)
- url = \"#{code}\"
- #{"url !~ @path_validation_regex ? nil : " if @dynamic} url
- end
- EOT
- else
- instance_eval "def raw_url(args, options); \"#{code}\"; end", __FILE__, __LINE__
- end
- end
end
end
end
View
10 lib/http_router/regex_route.rb
@@ -3,7 +3,8 @@ class RegexRoute < Route
def initialize(router, path, opts = {})
@router, @original_path, @opts = router, path, opts
@param_names = @original_path.respond_to?(:names) ? @original_path.names.map(&:to_sym) : []
- process_path_for_generation(opts.delete(:path_for_generation), @original_path) if opts.key?(:path_for_generation)
+ @path_validation_regex = original_path
+ Util.add_path_generation(self, self, opts.delete(:path_for_generation), @original_path) if opts.key?(:path_for_generation)
process_opts
end
@@ -27,5 +28,12 @@ def regex?
def generate_from?(params)
false
end
+
+ def url_with_params(*a)
+ url_args_processing(a) do |args, options|
+ respond_to?(:raw_url) or raise InvalidRouteException
+ raw_url(args, options)
+ end
+ end
end
end
View
14 lib/http_router/route.rb
@@ -138,13 +138,19 @@ def clone(new_router)
Route.new(new_router, @original_path.dup, as_options)
end
- def url_with_params(*args)
+ def url_with_params(*a)
+ url_args_processing(a) do |args, options|
+ path = args.empty? ? matching_path(options) : matching_path(args, options)
+ raise InvalidRouteException unless path
+ path.url(args, options)
+ end
+ end
+
+ def url_args_processing(args)
options = args.last.is_a?(Hash) ? args.pop : nil
options = options.nil? ? default_values.dup : default_values.merge(options) if default_values
options.delete_if{ |k,v| v.nil? } if options
- path = args.empty? ? matching_path(options) : matching_path(args, options)
- raise InvalidRouteException unless path
- result, params = path.url(args, options)
+ result, params = yield args, options
mount_point = router.url_mount && router.url_mount.url(options)
mount_point ? [File.join(mount_point, result), params] : [result, params]
end
View
36 lib/http_router/util.rb
@@ -0,0 +1,36 @@
+class HttpRouter
+ module Util
+ def self.add_path_generation(target, route, path, path_validation_regex = nil)
+ regex_parts = path.split(/([:\*][a-zA-Z0-9_]+)/)
+ regex, code = '', ''
+ dynamic = false
+ regex_parts.each_with_index do |part, index|
+ case part[0]
+ when ?:, ?*
+ if index != 0 && regex_parts[index - 1][-1] == ?\\
+ regex << Regexp.quote(part) unless path_validation_regex
+ code << part
+ dynamic = true
+ else
+ regex << (route.matches_with[part[1, part.size].to_sym] || '.*?').to_s unless path_validation_regex
+ code << "\#{args.shift || (options && options.delete(:#{part[1, part.size]})) || return}"
+ end
+ else
+ regex << Regexp.quote(part) unless path_validation_regex
+ code << part
+ end
+ end
+ path_validation_regex ||= Regexp.new("^#{regex}$") if dynamic
+ if path_validation_regex
+ target.instance_eval <<-EOT, __FILE__, __LINE__ + 1
+ def raw_url(args, options)
+ url = \"#{code}\"
+ #{"url !~ #{path_validation_regex.inspect} ? nil : " if @dynamic} url
+ end
+ EOT
+ else
+ target.instance_eval "def raw_url(args, options); \"#{code}\"; end", __FILE__, __LINE__
+ end
+ end
+ end
+end
View
14 test/test_misc.rb
@@ -43,4 +43,18 @@ def test_multi_name_gen
assert_equal '/name', r.url(:index, 'name')
assert_equal '/name/category', r.url(:index, 'name', 'category')
end
+
+ def test_regex_generation
+ r = HttpRouter.new
+ r.add(%r|/test/.*|, :path_for_generation => '/test/:variable').name(:route).default_destination
+ assert_equal '/test/var', r.url(:route, "var")
+ end
+
+ def test_regex_generation
+ r = HttpRouter.new
+ r.add(%r|/test/.*|, :path_for_generation => '/test/:variable').name(:route).default_destination
+ assert_equal '/test/var', r.url(:route, "var")
+ assert_equal '/test/var', r.url(:route, :variable => "var")
+ assert_raises(HttpRouter::InvalidRouteException) { r.url(:route) }
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.