Skip to content

Commit

Permalink
Added custom regexps to ASTs that have literal nodes on either side of
Browse files Browse the repository at this point in the history
symbol nodes.  Fixes #4585
  • Loading branch information
tenderlove committed Jan 24, 2012
1 parent bce3b5c commit 8d26f87
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
21 changes: 20 additions & 1 deletion actionpack/lib/action_dispatch/routing/route_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,26 @@ def build_path(path, requirements, separators, anchor)
SEPARATORS,
anchor)

Journey::Path::Pattern.new(strexp)
pattern = Journey::Path::Pattern.new(strexp)

builder = Journey::GTG::Builder.new pattern.spec

# Get all the symbol nodes followed by literals that are not the
# dummy node.
symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n|
builder.followpos(n).first.literal?
}

# Get all the symbol nodes preceded by literals.
symbols.concat pattern.spec.find_all(&:literal?).map { |n|
builder.followpos(n).first
}.find_all(&:symbol?)

symbols.each { |x|
x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/
}

pattern
end
private :build_path

Expand Down
62 changes: 62 additions & 0 deletions actionpack/test/controller/routing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,68 @@ def setup
@response = nil
end

def test_symbols_with_dashes
rs.draw do
match '/:artist/:song-omg', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end

hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
end

def test_id_with_dash
rs.draw do
match '/journey/:id', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end

hash = JSON.load get(URI('http://example.org/journey/faithfully-omg'))
assert_equal({"id"=>"faithfully-omg"}, hash)
end

def test_dash_with_custom_regexp
rs.draw do
match '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end

hash = JSON.load get(URI('http://example.org/journey/123-omg'))
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg'))
end

def test_pre_dash
rs.draw do
match '/:artist/omg-:song', :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end

hash = JSON.load get(URI('http://example.org/journey/omg-faithfully'))
assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash)
end

def test_pre_dash_with_custom_regexp
rs.draw do
match '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env|
resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY]
[200, {}, [resp]]
}
end

hash = JSON.load get(URI('http://example.org/journey/omg-123'))
assert_equal({"artist"=>"journey", "song"=>"123"}, hash)
assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully'))
end

def test_regexp_precidence
@rs.draw do
match '/whois/:domain', :constraints => {
Expand Down

0 comments on commit 8d26f87

Please sign in to comment.