Skip to content

Commit

Permalink
feat: type-safe check whether a route can be handled
Browse files Browse the repository at this point in the history
  • Loading branch information
programadorthi committed Apr 27, 2024
1 parent 82c784e commit 3adac4a
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 97 deletions.
35 changes: 23 additions & 12 deletions core/common/src/dev/programadorthi/routing/core/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ import kotlin.native.HiddenFromObjC
public class Routing internal constructor(
internal val application: Application,
) : Route(
parent = application.environment.parentRouting,
selector = RootRouteSelector(application.environment.rootPath),
application.environment.developmentMode,
application.environment,
) {
parent = application.environment.parentRouting,
selector = RootRouteSelector(application.environment.rootPath),
application.environment.developmentMode,
application.environment,
) {
private val tracers = mutableListOf<(RoutingResolveTrace) -> Unit>()
private val namedRoutes = mutableMapOf<String, Route>()
private var disposed = false
Expand All @@ -60,19 +60,27 @@ public class Routing internal constructor(
addDefaultTracing()
}

public fun canHandleByName(name: String, lookUpOnParent: Boolean = false): Boolean {
public fun canHandleByName(
name: String,
lookUpOnParent: Boolean = false,
): Boolean {
return when {
!lookUpOnParent -> namedRoutes.containsKey(name)
else -> generateSequence(seed = this) { it.parent?.asRouting }
.firstOrNull { it.namedRoutes.containsKey(name) } != null
else ->
generateSequence(seed = this) { it.parent?.asRouting }
.firstOrNull { it.namedRoutes.containsKey(name) } != null
}
}

public fun canHandleByPath(path: String, lookUpOnParent: Boolean = false): Boolean {
public fun canHandleByPath(
path: String,
lookUpOnParent: Boolean = false,
): Boolean {
return when {
!lookUpOnParent -> canHandleByPath(path = path, routing = this)
else -> generateSequence(seed = this) { it.parent?.asRouting }
.firstOrNull { canHandleByPath(path = path, routing = it) } != null
else ->
generateSequence(seed = this) { it.parent?.asRouting }
.firstOrNull { canHandleByPath(path = path, routing = it) } != null
}
}

Expand Down Expand Up @@ -133,7 +141,10 @@ public class Routing internal constructor(
namedRoutes[name] = route
}

private fun canHandleByPath(path: String, routing: Routing): Boolean {
private fun canHandleByPath(
path: String,
routing: Routing,
): Boolean {
var routingChildren = routing.children
var hasHandle = false

Expand Down
183 changes: 98 additions & 85 deletions core/common/test/dev/programadorthi/routing/core/RoutingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,10 @@ class RoutingTest {
routing.call(
name = "named",
parameters =
parametersOf(
"id" to listOf("123"),
"name" to listOf("routing"),
),
parametersOf(
"id" to listOf("123"),
"name" to listOf("routing"),
),
)
advanceTimeBy(99)

Expand Down Expand Up @@ -343,7 +343,7 @@ class RoutingTest {
handle {
call.redirectToName(
name = "path2",
parameters = parametersOf("key", "value")
parameters = parametersOf("key", "value"),
)
}
}
Expand Down Expand Up @@ -379,10 +379,10 @@ class RoutingTest {
call.redirectToName(
name = "path2",
parameters =
parametersOf(
"id" to listOf("123"),
"key" to listOf("value"),
),
parametersOf(
"id" to listOf("123"),
"key" to listOf("value"),
),
)
}
}
Expand Down Expand Up @@ -1585,12 +1585,13 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByANamedRoute() {
// GIVEN
val routing = routing {
route(path = "/path", name = "path") {
handle {
val routing =
routing {
route(path = "/path", name = "path") {
handle {
}
}
}
}

// WHEN
val result = routing.canHandleByName(name = "path")
Expand Down Expand Up @@ -1620,12 +1621,13 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByANamedRouteOnParent() {
// GIVEN
val parent = routing {
route(path = "/path", name = "path") {
handle {
val parent =
routing {
route(path = "/path", name = "path") {
handle {
}
}
}
}
val routing = routing(parent = parent, rootPath = "/child") {}

// WHEN
Expand All @@ -1638,12 +1640,13 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByANamedRouteOnParent() {
// GIVEN
val parent = routing {
route(path = "/path") {
handle {
val parent =
routing {
route(path = "/path") {
handle {
}
}
}
}
val routing = routing(parent = parent, rootPath = "/child") {}

// WHEN
Expand All @@ -1656,12 +1659,13 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByAPath() {
// GIVEN
val routing = routing {
route(path = "/path") {
handle {
val routing =
routing {
route(path = "/path") {
handle {
}
}
}
}

// WHEN
val result = routing.canHandleByPath(path = "/path")
Expand All @@ -1673,12 +1677,13 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByAPath() {
// GIVEN
val routing = routing {
route(path = "/other") {
handle {
val routing =
routing {
route(path = "/other") {
handle {
}
}
}
}

// WHEN
val result = routing.canHandleByPath(path = "/path")
Expand All @@ -1690,17 +1695,17 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByAPathWithMultiLevel() {
// GIVEN
val routing = routing {
route(path = "/level1") {
route(path = "/level2") {
route(path = "/level3") {
handle {

val routing =
routing {
route(path = "/level1") {
route(path = "/level2") {
route(path = "/level3") {
handle {
}
}
}
}
}
}

// WHEN
val result = routing.canHandleByPath(path = "/level1/level2/level3")
Expand All @@ -1712,13 +1717,13 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByAPathWithMultiLevel() {
// GIVEN
val routing = routing {
route(path = "/level1") {
handle {

val routing =
routing {
route(path = "/level1") {
handle {
}
}
}
}

// WHEN
val result = routing.canHandleByPath(path = "/level1/level2/level3")
Expand All @@ -1730,12 +1735,13 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByAPathOnParent() {
// GIVEN
val parent = routing {
route(path = "/path") {
handle {
val parent =
routing {
route(path = "/path") {
handle {
}
}
}
}
val routing = routing(parent = parent, rootPath = "/child") {}

// WHEN
Expand All @@ -1748,12 +1754,13 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByAPathOnParent() {
// GIVEN
val parent = routing {
route(path = "/path") {
handle {
val parent =
routing {
route(path = "/path") {
handle {
}
}
}
}
val routing = routing(parent = parent, rootPath = "/child") {}

// WHEN
Expand All @@ -1766,17 +1773,17 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByAPathWithMultiLevelOnParent() {
// GIVEN
val parent = routing {
route(path = "/level1") {
route(path = "/level2") {
route(path = "/level3") {
handle {

val parent =
routing {
route(path = "/level1") {
route(path = "/level2") {
route(path = "/level3") {
handle {
}
}
}
}
}
}
val routing = routing(parent = parent, rootPath = "/child") {}

// WHEN
Expand All @@ -1789,13 +1796,13 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByAPathWithMultiLevelOnParent() {
// GIVEN
val routing = routing {
route(path = "/level1") {
handle {

val routing =
routing {
route(path = "/level1") {
handle {
}
}
}
}

// WHEN
val result = routing.canHandleByPath(path = "/level1/level2/level3", lookUpOnParent = true)
Expand All @@ -1807,24 +1814,27 @@ class RoutingTest {
@Test
fun shouldReturnsTrueWhenCanHandleByAPathInNestedRouting() {
// GIVEN
val parent = routing {
route(path = "/parent") {
handle {
val parent =
routing {
route(path = "/parent") {
handle {
}
}
}
}
val child = routing(parent = parent, rootPath = "/child") {
route(path = "/childPath") {
handle {
val child =
routing(parent = parent, rootPath = "/child") {
route(path = "/childPath") {
handle {
}
}
}
}
val grandchild = routing(parent = child, rootPath = "/grandchild") {
route(path = "/grandchildPath") {
handle {
val grandchild =
routing(parent = child, rootPath = "/grandchild") {
route(path = "/grandchildPath") {
handle {
}
}
}
}

// WHEN
val result = grandchild.canHandleByPath(path = "/child/childPath", lookUpOnParent = true)
Expand All @@ -1836,24 +1846,27 @@ class RoutingTest {
@Test
fun shouldReturnsFalseWhenCanNotHandleByAPathInNestedRouting() {
// GIVEN
val parent = routing {
route(path = "/parent") {
handle {
val parent =
routing {
route(path = "/parent") {
handle {
}
}
}
}
val child = routing(parent = parent, rootPath = "/child") {
route(path = "/childPath") {
handle {
val child =
routing(parent = parent, rootPath = "/child") {
route(path = "/childPath") {
handle {
}
}
}
}
val grandchild = routing(parent = child, rootPath = "/grandchild") {
route(path = "/grandchildPath") {
handle {
val grandchild =
routing(parent = child, rootPath = "/grandchild") {
route(path = "/grandchildPath") {
handle {
}
}
}
}

// WHEN
val result =
Expand Down
Loading

0 comments on commit 3adac4a

Please sign in to comment.