require 'abstract_unit'
module ActionDispatch
module Journey
module Path
class TestPattern < ActiveSupport::TestCase
SEPARATORS = ["/", ".", "?"].join
x = /.+/
{
'/:controller(/:action)' => %r{\A/(#{x})(?:/([^/.?]+))?\Z},
'/:controller/foo' => %r{\A/(#{x})/foo\Z},
'/:controller/:action' => %r{\A/(#{x})/([^/.?]+)\Z},
'/:controller' => %r{\A/(#{x})\Z},
'/:controller(/:action(/:id))' => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z},
'/:controller/:action.xml' => %r{\A/(#{x})/([^/.?]+)\.xml\Z},
'/:controller.:format' => %r{\A/(#{x})\.([^/.?]+)\Z},
'/:controller(.:format)' => %r{\A/(#{x})(?:\.([^/.?]+))?\Z},
'/:controller/*foo' => %r{\A/(#{x})/(.+)\Z},
'/:controller/*foo/bar' => %r{\A/(#{x})/(.+)/bar\Z},
'/:foo|*bar' => %r{\A/(?:([^/.?]+)|(.+))\Z},
}.each do |path, expected|
define_method(:"test_to_regexp_#{path}") do
path = Pattern.build(
path,
{ :controller => /.+/ },
SEPARATORS,
true
)
assert_equal(expected, path.to_regexp)
end
end
{
'/:controller(/:action)' => %r{\A/(#{x})(?:/([^/.?]+))?},
'/:controller/foo' => %r{\A/(#{x})/foo},
'/:controller/:action' => %r{\A/(#{x})/([^/.?]+)},
'/:controller' => %r{\A/(#{x})},
'/:controller(/:action(/:id))' => %r{\A/(#{x})(?:/([^/.?]+)(?:/([^/.?]+))?)?},
'/:controller/:action.xml' => %r{\A/(#{x})/([^/.?]+)\.xml},
'/:controller.:format' => %r{\A/(#{x})\.([^/.?]+)},
'/:controller(.:format)' => %r{\A/(#{x})(?:\.([^/.?]+))?},
'/:controller/*foo' => %r{\A/(#{x})/(.+)},
'/:controller/*foo/bar' => %r{\A/(#{x})/(.+)/bar},
'/:foo|*bar' => %r{\A/(?:([^/.?]+)|(.+))},
}.each do |path, expected|
define_method(:"test_to_non_anchored_regexp_#{path}") do
path = Pattern.build(
path,
{ :controller => /.+/ },
SEPARATORS,
false
)
assert_equal(expected, path.to_regexp)
end
end
{
'/:controller(/:action)' => %w{ controller action },
'/:controller/foo' => %w{ controller },
'/:controller/:action' => %w{ controller action },
'/:controller' => %w{ controller },
'/:controller(/:action(/:id))' => %w{ controller action id },
'/:controller/:action.xml' => %w{ controller action },
'/:controller.:format' => %w{ controller format },
'/:controller(.:format)' => %w{ controller format },
'/:controller/*foo' => %w{ controller foo },
'/:controller/*foo/bar' => %w{ controller foo },
}.each do |path, expected|
define_method(:"test_names_#{path}") do
path = Pattern.build(
path,
{ :controller => /.+/ },
SEPARATORS,
true
)
assert_equal(expected, path.names)
end
end
def test_to_regexp_with_extended_group
path = Pattern.build(
'/page/:name',
{ :name => /
#ROFL
(tender|love
#MAO
)/x },
SEPARATORS,
true
)
assert_match(path, '/page/tender')
assert_match(path, '/page/love')
assert_no_match(path, '/page/loving')
end
def test_optional_names
[
['/:foo(/:bar(/:baz))', %w{ bar baz }],
['/:foo(/:bar)', %w{ bar }],
['/:foo(/:bar)/:lol(/:baz)', %w{ bar baz }],
].each do |pattern, list|
path = Pattern.from_string pattern
assert_equal list.sort, path.optional_names.sort
end
end
def test_to_regexp_match_non_optional
path = Pattern.build(
'/:name',
{ :name => /\d+/ },
SEPARATORS,
true
)
assert_match(path, '/123')
assert_no_match(path, '/')
end
def test_to_regexp_with_group
path = Pattern.build(
'/page/:name',
{ :name => /(tender|love)/ },
SEPARATORS,
true
)
assert_match(path, '/page/tender')
assert_match(path, '/page/love')
assert_no_match(path, '/page/loving')
end
def test_ast_sets_regular_expressions
requirements = { :name => /(tender|love)/, :value => /./ }
path = Pattern.build(
'/page/:name/:value',
requirements,
SEPARATORS,
true
)
nodes = path.ast.grep(Nodes::Symbol)
assert_equal 2, nodes.length
nodes.each do |node|
assert_equal requirements[node.to_sym], node.regexp
end
end
def test_match_data_with_group
path = Pattern.build(
'/page/:name',
{ :name => /(tender|love)/ },
SEPARATORS,
true
)
match = path.match '/page/tender'
assert_equal 'tender', match[1]
assert_equal 2, match.length
end
def test_match_data_with_multi_group
path = Pattern.build(
'/page/:name/:id',
{ :name => /t(((ender|love)))()/ },
SEPARATORS,
true
)
match = path.match '/page/tender/10'
assert_equal 'tender', match[1]
assert_equal '10', match[2]
assert_equal 3, match.length
assert_equal %w{ tender 10 }, match.captures
end
def test_star_with_custom_re
z = /\d+/
path = Pattern.build(
'/page/*foo',
{ :foo => z },
SEPARATORS,
true
)
assert_equal(%r{\A/page/(#{z})\Z}, path.to_regexp)
end
def test_insensitive_regexp_with_group
path = Pattern.build(
'/page/:name/aaron',
{ :name => /(tender|love)/i },
SEPARATORS,
true
)
assert_match(path, '/page/TENDER/aaron')
assert_match(path, '/page/loVE/aaron')
assert_no_match(path, '/page/loVE/AAron')
end
def test_to_regexp_with_strexp
path = Pattern.build('/:controller', { }, SEPARATORS, true)
x = %r{\A/([^/.?]+)\Z}
assert_equal(x.source, path.source)
end
def test_to_regexp_defaults
path = Pattern.from_string '/:controller(/:action(/:id))'
expected = %r{\A/([^/.?]+)(?:/([^/.?]+)(?:/([^/.?]+))?)?\Z}
assert_equal expected, path.to_regexp
end
def test_failed_match
path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
uri = 'content'
assert_not path =~ uri
end
def test_match_controller
path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
uri = '/content'
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
assert_equal 'content', match[1]
assert_nil match[2]
assert_nil match[3]
assert_nil match[4]
end
def test_match_controller_action
path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
uri = '/content/list'
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
assert_equal 'content', match[1]
assert_equal 'list', match[2]
assert_nil match[3]
assert_nil match[4]
end
def test_match_controller_action_id
path = Pattern.from_string '/:controller(/:action(/:id(.:format)))'
uri = '/content/list/10'
match = path =~ uri
assert_equal %w{ controller action id format }, match.names
assert_equal 'content', match[1]
assert_equal 'list', match[2]
assert_equal '10', match[3]
assert_nil match[4]
end
def test_match_literal
path = Path::Pattern.from_string "/books(/:action(.:format))"
uri = '/books'
match = path =~ uri
assert_equal %w{ action format }, match.names
assert_nil match[1]
assert_nil match[2]
end
def test_match_literal_with_action
path = Path::Pattern.from_string "/books(/:action(.:format))"
uri = '/books/list'
match = path =~ uri
assert_equal %w{ action format }, match.names
assert_equal 'list', match[1]
assert_nil match[2]
end
def test_match_literal_with_action_and_format
path = Path::Pattern.from_string "/books(/:action(.:format))"
uri = '/books/list.rss'
match = path =~ uri
assert_equal %w{ action format }, match.names
assert_equal 'list', match[1]
assert_equal 'rss', match[2]
end
end
end
end
end