Skip to content
This repository has been archived by the owner on Sep 30, 2018. It is now read-only.

Commit

Permalink
Support optional (named) segments inside Route paths
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Nov 29, 2013
1 parent 9d8e9d1 commit 4c009d8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
3 changes: 3 additions & 0 deletions opal/vienna/router.rb
Expand Up @@ -44,12 +44,15 @@ class Route
# Regexp for matching named splats in path
SPLAT = /\\\*(\w+)/

OPTIONAL = /\\\((.*?)\\\)/

attr_reader :regexp, :named

def initialize(pattern, &handler)
@named, @handler = [], handler

pattern = Regexp.escape pattern
pattern = pattern.gsub OPTIONAL, "(?:$1)?"

pattern.gsub(NAMED) { |m| @named << m[1..-1] }
pattern.gsub(SPLAT) { |m| @named << m[2..-1] }
Expand Down
30 changes: 28 additions & 2 deletions spec/route_spec.rb
Expand Up @@ -57,7 +57,33 @@
subject.new('/:first/:second') { |params|
params.should eq({ 'first' => 'woosh', 'second' => 'kapow' })
}.match('/woosh/kapow')
end
end

describe "optional segment" do
it "can match simple optional segments" do
route = subject.new('/foo(/bar)')

expect(route.match('/foo')).to eq(true)
expect(route.match('/foo/bar')).to eq(true)
expect(route.match('/foo/baz')).to_not eq(true)
end

it "can match a named part inside an optional part" do
route = subject.new('/foo(/:bar)')
expect(route.named).to eq(['bar'])
end

it "returns set named part to nil when optional part not given" do
subject.new('/foo(/:bar)') { |params|
params.should eq({ 'bar' => nil })
}.match('/foo')
end

it "returns correct value for named param inside optional part" do
subject.new('/foo(/:bar)') { |params|
params.should eq({ 'bar' => '42' })
}.match('/foo/42')
end
end
end
end

0 comments on commit 4c009d8

Please sign in to comment.