Skip to content

Commit

Permalink
Merge pull request scalatra#113 from ornicar/urlGeneratorFullSinatraS…
Browse files Browse the repository at this point in the history
…upport

Url generator full sinatra support
  • Loading branch information
casualjim committed Aug 20, 2011
2 parents 55fc625 + d4414ce commit 2effb3b
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
23 changes: 18 additions & 5 deletions core/src/main/scala/org/scalatra/routeMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,25 @@ final class SinatraRouteMatcher(path: String, requestPath: => String)
{
def apply() = SinatraPathPatternParser(path)(requestPath)

def reverse(params: Map[String, String], splats: List[String]): String =
replaceSplats(replaceNamedParams(params), splats)
def reverse(params: Map[String, String], splats: List[String]): String = {
replaceSplats(
replaceNamedParams(
replaceOptionalParams(path, params),
params
), splats)
}

private def replaceNamedParams(params: Map[String, String]) =
""":[^/?#\.]+""".r replaceAllIn (path, s =>
params.get(s.toString.tail) match {
private def replaceOptionalParams(slug: String, params: Map[String, String]): String =
"""[\./]\?:[^/?#\.]+\?""".r replaceAllIn (path, s => {
params.get(s.matched slice (3, s.matched.size - 1)) match {
case Some(value) => s.matched.head + value
case None => ""
}
})

private def replaceNamedParams(slug: String, params: Map[String, String]): String =
""":[^/?#\.]+""".r replaceAllIn (slug, s =>
params.get(s.matched.tail) match {
case Some(value) => value
case None => throw new Exception("The url \"%s\" requires param \"%s\"" format (path, s))
})
Expand Down
12 changes: 12 additions & 0 deletions core/src/test/scala/org/scalatra/RouteTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ class RouteTestServlet extends ScalatraServlet {
(for (key <- List("foo", "bar") if params.isDefinedAt(key)) yield key+"="+params(key)).mkString(";")
}

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

get("/single-splat/*") {
multiParams.getOrElse("splat", Seq.empty).mkString(":")
}
Expand Down Expand Up @@ -124,6 +128,14 @@ class RouteTest extends ScalatraFunSuite {
get("/optional") {
body should equal ("")
}

get("/optional-ext.json") {
body should equal ("ext=json")
}

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

test("supports single splat params") {
Expand Down
18 changes: 18 additions & 0 deletions core/src/test/scala/org/scalatra/UrlGeneratorTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ class UrlGeneratorTest extends ScalatraFunSuite {
} should produce [Exception]
}

test("Optional parameters can be provided") {
url(optional, "foo" -> "a", "bar" -> "b") should equal ("/optional/a/b")
}

test("Optional parameters can be partially missing") {
url(optional, "foo" -> "a") should equal ("/optional/a")
url(optional, "bar" -> "b") should equal ("/optional/b")
}

test("Optional parameters can be all missing") {
url(optional) should equal ("/optional")
}

//test("Optional parameter following a dot can drop the dot") {
//url(optionalExt) should equal ("/optional-ext")
//url(optionalExt, "ext" -> "json") should equal ("/optional-ext.json")
//}

test("Unexpected parameters are just ignored at the moment") {
url(singleNamed, "bar" -> "pepper", "unexpected" -> "surprise") should equal ("/foo/pepper")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class UrlGeneratorTestServlet extends ScalatraServlet with ReverseRoutingSupport

val optional = get("/optional/?:foo?/?:bar?") { }

val optionalExt = get("/optional-ext.?:ext?") { }

val singleSplat = get("/single-splat/*") { }

val multipleSplats = get("/mixing-multiple-splats/*/foo/*/*") { }
Expand Down

0 comments on commit 2effb3b

Please sign in to comment.