Skip to content

Commit

Permalink
Support optional named route parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
rossabaker committed Apr 9, 2010
1 parent 44f6f24 commit c95bfd7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/main/scala/com/thinkminimo/step/StepKernel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,16 @@ trait StepKernel
protected implicit def string2RouteMatcher(path: String): RouteMatcher = {
val pattern = """:\w+"""
val names = new Regex(pattern) findAllIn path toList
val re = new Regex("^%s$" format path.replaceAll(pattern, "(.+?)"))
val re = new Regex("^%s$" format path.replaceAll(pattern, "([^/?]+)"))
// By overriding toString, we can list the available routes in the default notFound handler.
new RouteMatcher {
def apply() = re findFirstMatchIn requestPath map (x => Map(names zip (x.subgroups map { Seq(_) }) : _*))
def apply() = (re findFirstMatchIn requestPath)
.map { reMatch => names zip reMatch.subgroups }
.map { pairs =>
// filter out nulls (i.e., unset optional parameters) and build a multimap
Map(pairs flatMap { case (k, v) => if (v != null) Some(k, Seq(v)) else None } : _*)
}

override def toString = path
}
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/scala/com/thinkminimo/step/RouteTest.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Most of these test cases are ported from http://github.com/sinatra/sinatra/tree master/test/routing_test.rb
*/
package com.thinkminimo.step

import org.scalatest.matchers.ShouldMatchers
Expand All @@ -6,6 +9,10 @@ class RouteTestServlet extends Step {
get(params.getOrElse("booleanTest", "false") == "true") {
"matched boolean route"
}

get("/optional/?:foo?/?:bar?") {
(for (key <- List(":foo", ":bar") if params.isDefinedAt(key)) yield key+"="+params(key)).mkString(";")
}
}

class RouteTest extends StepSuite with ShouldMatchers {
Expand All @@ -16,4 +23,18 @@ class RouteTest extends StepSuite with ShouldMatchers {
body should equal ("matched boolean route")
}
}

test("supports optional named params") {
get("/optional/hello/world") {
body should equal (":foo=hello;:bar=world")
}

get("/optional/hello") {
body should equal (":foo=hello")
}

get("/optional") {
body should equal ("")
}
}
}

0 comments on commit c95bfd7

Please sign in to comment.