From 437d1bef05c1dad7123fc828b4b2b80b9f2b592d Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 5 Jan 2024 13:01:06 +0800 Subject: [PATCH] tweaktests --- cask/src/cask/internal/DispatchTrie.scala | 24 +++++---- .../src/test/cask/DispatchTrieTests.scala | 50 +++++++++---------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/cask/src/cask/internal/DispatchTrie.scala b/cask/src/cask/internal/DispatchTrie.scala index 07e4f6e4f0..ab9d610b4a 100644 --- a/cask/src/cask/internal/DispatchTrie.scala +++ b/cask/src/cask/internal/DispatchTrie.scala @@ -4,24 +4,28 @@ object DispatchTrie{ def construct[T, V](index: Int, inputs: collection.Seq[(collection.IndexedSeq[String], T, Boolean)]) (validationGroups: T => Seq[V]): DispatchTrie[T] = { - val continuations = mutable.Map.empty[String, mutable.Buffer[(collection.IndexedSeq[String], T, Boolean)]] + val continuations = mutable.Map.empty[String, (String, mutable.Buffer[(collection.IndexedSeq[String], T, Boolean)])] val terminals = mutable.Buffer.empty[(collection.IndexedSeq[String], T, Boolean)] for((path, endPoint, allowSubpath) <- inputs) { if (path.length < index) () // do nothing else if (path.length == index) terminals.append((path, endPoint, allowSubpath)) else if (path.length > index){ - val buf = continuations.getOrElseUpdate(path(index), mutable.Buffer.empty) - buf.append((path, endPoint, allowSubpath)) + val segment = path(index) + val buf = continuations.getOrElseUpdate( + if (segment.startsWith(":")) ":" else segment, + (segment, mutable.Buffer.empty) + ) + buf._2.append((path, endPoint, allowSubpath)) } } - validateGroups(inputs, terminals, continuations)(validationGroups) + validateGroups(inputs, terminals, continuations.map{case (k, (k2, v)) => (k, v)})(validationGroups) DispatchTrie[T]( current = terminals.headOption.map(x => x._2 -> x._3), children = continuations - .map{ case (k, vs) => (k, construct(index + 1, vs)(validationGroups))} + .map{ case (k, (k2, vs)) => (k, (k2, construct(index + 1, vs)(validationGroups)))} .toMap ) } @@ -51,6 +55,7 @@ object DispatchTrie{ def render(values: collection.Seq[(collection.IndexedSeq[String], T, Boolean, V)]) = values .map { case (path, v, allowSubpath, group) => s"$group /" + path.mkString("/") } + .sorted .mkString(", ") def renderTerminals = render(terminals) @@ -86,7 +91,7 @@ object DispatchTrie{ * segments) */ case class DispatchTrie[T](current: Option[(T, Boolean)], - children: Map[String, DispatchTrie[T]]){ + children: Map[String, (String, DispatchTrie[T])]){ final def lookup(remainingInput: List[String], bindings: Map[String, String]) : Option[(T, Map[String, String], Seq[String])] = { @@ -97,11 +102,12 @@ case class DispatchTrie[T](current: Option[(T, Boolean)], current.map(x => (x._1, bindings, head :: rest)) case head :: rest => if (children.size == 1 && children.keys.head.startsWith(":")){ - children.values.head.lookup(rest, bindings + (children.keys.head.drop(1) -> head)) + val (k, (k2, v)) = children.head + v.lookup(rest, bindings + (k2.drop(1) -> head)) }else{ children.get(head) match{ case None => None - case Some(continuation) => continuation.lookup(rest, bindings) + case Some((k2, continuation)) => continuation.lookup(rest, bindings) } } @@ -110,6 +116,6 @@ case class DispatchTrie[T](current: Option[(T, Boolean)], def map[V](f: T => V): DispatchTrie[V] = DispatchTrie( current.map{case (t, v) => (f(t), v)}, - children.map { case (k, v) => (k, v.map(f))} + children.map { case (k, (k2, v)) => (k, (k2, v.map(f)))} ) } diff --git a/cask/test/src/test/cask/DispatchTrieTests.scala b/cask/test/src/test/cask/DispatchTrieTests.scala index 92893b24fd..7654f0e7ef 100644 --- a/cask/test/src/test/cask/DispatchTrieTests.scala +++ b/cask/test/src/test/cask/DispatchTrieTests.scala @@ -7,10 +7,10 @@ object DispatchTrieTests extends TestSuite { test("hello") { val x = DispatchTrie.construct(0, - Seq((Vector("hello"), "GET", false)) + Seq((Vector("hello"), ("GET", "fooImpl"), false)) )(Seq(_)) - x.lookup(List("hello"), Map()) ==> Some(("GET", Map(), Nil)) + x.lookup(List("hello"), Map()) ==> Some((("GET", "fooImpl"), Map(), Nil)) x.lookup(List("hello", "world"), Map()) ==> None x.lookup(List("world"), Map()) ==> None @@ -18,13 +18,13 @@ object DispatchTrieTests extends TestSuite { test("nested") { val x = DispatchTrie.construct(0, Seq( - (Vector("hello", "world"), "GET", false), - (Vector("hello", "cow"), "POST", false) + (Vector("hello", "world"), ("GET", "fooImpl"), false), + (Vector("hello", "cow"), ("GET", "barImpl"), false) ) )(Seq(_)) - x.lookup(List("hello", "world"), Map()) ==> Some(("GET", Map(), Nil)) - x.lookup(List("hello", "cow"), Map()) ==> Some(("POST", Map(), Nil)) + x.lookup(List("hello", "world"), Map()) ==> Some((("GET", "fooImpl"), Map(), Nil)) + x.lookup(List("hello", "cow"), Map()) ==> Some((("GET", "barImpl"), Map(), Nil)) x.lookup(List("hello"), Map()) ==> None x.lookup(List("hello", "moo"), Map()) ==> None @@ -33,11 +33,11 @@ object DispatchTrieTests extends TestSuite { } test("bindings") { val x = DispatchTrie.construct(0, - Seq((Vector(":hello", ":world"), "GET", false)) + Seq((Vector(":hello", ":world"), ("GET", "fooImpl"), false)) )(Seq(_)) - x.lookup(List("hello", "world"), Map()) ==> Some(("GET", Map("hello" -> "hello", "world" -> "world"), Nil)) - x.lookup(List("world", "hello"), Map()) ==> Some(("GET", Map("hello" -> "world", "world" -> "hello"), Nil)) + x.lookup(List("hello", "world"), Map()) ==> Some((("GET", "fooImpl"), Map("hello" -> "hello", "world" -> "world"), Nil)) + x.lookup(List("world", "hello"), Map()) ==> Some((("GET", "fooImpl"), Map("hello" -> "world", "world" -> "hello"), Nil)) x.lookup(List("hello", "world", "cow"), Map()) ==> None x.lookup(List("hello"), Map()) ==> None @@ -46,12 +46,12 @@ object DispatchTrieTests extends TestSuite { test("path") { val x = DispatchTrie.construct(0, - Seq((Vector("hello"), "GET", true)) + Seq((Vector("hello"), ("GET", "fooImpl"), true)) )(Seq(_)) - x.lookup(List("hello", "world"), Map()) ==> Some(("GET", Map(), Seq("world"))) - x.lookup(List("hello", "world", "cow"), Map()) ==> Some(("GET", Map(), Seq("world", "cow"))) - x.lookup(List("hello"), Map()) ==> Some(("GET", Map(), Seq())) + x.lookup(List("hello", "world"), Map()) ==> Some((("GET", "fooImpl"), Map(), Seq("world"))) + x.lookup(List("hello", "world", "cow"), Map()) ==> Some((("GET", "fooImpl"), Map(), Seq("world", "cow"))) + x.lookup(List("hello"), Map()) ==> Some((("GET", "fooImpl"), Map(), Seq())) x.lookup(List(), Map()) == None } @@ -60,8 +60,8 @@ object DispatchTrieTests extends TestSuite { test("wildcardAndFixedWildcard"){ val x = DispatchTrie.construct(0, Seq( - (Vector(":hello"), "GET", false), - (Vector("hello", ":world"), "GET", false) + (Vector(":hello"), ("GET", "fooImpl"), false), + (Vector("hello", ":world"), ("GET", "barImpl"), false) ) )(Seq(_)) @@ -76,13 +76,13 @@ object DispatchTrieTests extends TestSuite { test("wildcardAndSameWildcardFixed") { val x = DispatchTrie.construct(0, Seq( - (Vector(":hello"), "GET", false), - (Vector(":hello", "world"), "GET", false) + (Vector(":hello"), ("GET", "fooImpl"), false), + (Vector(":hello", "world"), ("GET", "barImpl"), false) ) )(Seq(_)) - x.lookup(List("hello", "world"), Map()) ==> Some(("GET", Map("hello" -> "hello"), Nil)) - x.lookup(List("hello"), Map()) ==> Some(("GET", Map("hello" -> "hello"), Nil)) + x.lookup(List("hello"), Map()) ==> Some((("GET", "fooImpl"), Map("hello" -> "hello"), Nil)) + x.lookup(List("hello", "world"), Map()) ==> Some((("GET", "barImpl"), Map("hello" -> "hello"), Nil)) x.lookup(List("world", "hello"), Map()) ==> None x.lookup(List("hello", "world", "cow"), Map()) ==> None @@ -121,13 +121,13 @@ object DispatchTrieTests extends TestSuite { test("differingWildcardDifferingFixed") { val x = DispatchTrie.construct(0, Seq( - (Vector(":hello", "foo"), "GET", false), - (Vector(":world", "bar"), "GET", false) + (Vector(":hello", "foo"), ("GET", "fooImpl"), false), + (Vector(":world", "bar"), ("GET", "barImpl"), false) ) )(Seq(_)) - x.lookup(List("hello", "world"), Map()) ==> Some(("GET", Map("hello" -> "hello", "world" -> "world"), Nil)) - x.lookup(List("world", "hello"), Map()) ==> Some(("GET", Map("hello" -> "world", "world" -> "hello"), Nil)) + x.lookup(List("hello", "foo"), Map()) ==> Some((("GET", "fooImpl"), Map("hello" -> "hello"), Nil)) + x.lookup(List("world", "bar"), Map()) ==> Some((("GET", "barImpl"), Map("world" -> "world"), Nil)) x.lookup(List("hello", "world", "cow"), Map()) ==> None x.lookup(List("hello"), Map()) ==> None @@ -200,7 +200,7 @@ object DispatchTrieTests extends TestSuite { assert( ex.getMessage == - "Routes overlap with wildcards: GET /hello/:world, GET /hello/:cow" + "More than one endpoint has the same path: GET /hello/:cow, GET /hello/:world" ) } test("wildcardAndWildcardPrefix") { @@ -222,7 +222,7 @@ object DispatchTrieTests extends TestSuite { assert( ex.getMessage == - "Routes overlap with wildcards: GET /:world/hello, GET /:cow/hello" + "More than one endpoint has the same path: GET /:cow/hello, GET /:world/hello" ) } test("fixedAndFixed") {