Skip to content

Commit 9459338

Browse files
committed
Added support for regex in path spec. Supports adding :captures path_info element for any capture groups
1 parent bc7b147 commit 9459338

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

lib/webmachine/dispatcher/route.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ def bind(tokens, bindings)
119119
return [depth, tokens]
120120
when tokens.empty?
121121
return false
122+
when Regexp === spec.first
123+
matches = spec.first.match URI.decode(tokens.first)
124+
if matches
125+
bindings[:captures] = (bindings[:captures] || []) + matches.captures
126+
else
127+
return false
128+
end
122129
when Symbol === spec.first
123130
bindings[spec.first] = URI.decode(tokens.first)
124131
when spec.first == tokens.first

spec/webmachine/dispatcher/route_spec.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ def call(request)
180180
end
181181
end
182182
end
183-
184183
context "on a deep path" do
185184
subject { described_class.new(%w{foo bar baz}, resource) }
186185
let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz") }
@@ -205,6 +204,21 @@ def call(request)
205204
expect(request.path_info).to eq({:id => "bar"})
206205
end
207206
end
207+
context "with regex" do
208+
subject { described_class.new([/foo/, /(.*)/, 'baz'], resource) }
209+
210+
it "should assign the captures path variables" do
211+
expect(request.path_info).to eq({:captures => ["bar"]})
212+
end
213+
end
214+
context "with multi-capture regex" do
215+
subject { described_class.new([/foo/, /(.*)/, /baz\.(.*)/], resource) }
216+
let(:uri) { URI.parse("http://localhost:8080/foo/bar/baz.json") }
217+
218+
it "should assign the captures path variables" do
219+
expect(request.path_info).to eq({:captures => ["bar", "json"]})
220+
end
221+
end
208222

209223
context "with a splat" do
210224
subject { described_class.new(['foo', :*], resource) }

spec/webmachine/dispatcher_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
describe Webmachine::Dispatcher do
44
let(:dispatcher) { Webmachine.application.dispatcher }
55
let(:request) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/"), Webmachine::Headers["accept" => "*/*"], "") }
6+
let(:request2) { Webmachine::Request.new("GET", URI.parse("http://localhost:8080/hello/bob.html"), Webmachine::Headers["accept" => "*/*"], "") }
67
let(:response) { Webmachine::Response.new }
78
let(:resource) do
89
Class.new(Webmachine::Resource) do
@@ -14,6 +15,14 @@ def to_html; "hello world!"; end
1415
def to_html; "goodbye, cruel world"; end
1516
end
1617
end
18+
let(:resource3) do
19+
Class.new(Webmachine::Resource) do
20+
def to_html
21+
name, format = request.path_info[:captures]
22+
"Hello #{name} with #{format}"
23+
end
24+
end
25+
end
1726
let(:fsm){ double }
1827

1928
before { dispatcher.reset }
@@ -44,6 +53,12 @@ def to_html; "goodbye, cruel world"; end
4453
expect(fsm).to receive(:run)
4554
dispatcher.dispatch(request, response)
4655
end
56+
it "should handle regex path segments in route definition" do
57+
dispatcher.add_route ["hello", /(.*)\.(.*)/], resource3
58+
expect(Webmachine::Decision::FSM).to receive(:new).with(instance_of(resource3), request2, response).and_return(fsm)
59+
expect(fsm).to receive(:run)
60+
dispatcher.dispatch(request2, response)
61+
end
4762

4863
it "should apply route to request before creating the resource" do
4964
route = dispatcher.add_route [:*], resource

0 commit comments

Comments
 (0)