Routes New

Additional

Language
Kotlin
Version
N/A
Created
Jun 19, 2020
Updated
Jun 19, 2020
Owner
Greg Hynds (greghynds)
Contributor
Greg Hynds (greghynds)
1
Activity
Badge
Generate
Download
Source code

Announcement

Routes

A tiny Android library for testable navigation logic

Intro

Navigating to different screens on Android is handled by starting an Intent, but the Intent class can't be used in unit tests because it depends on Android's Context, which is only available at runtime. This makes it difficult to write test scenarios that can check our app is navigating to the right place with the right parameters.

A Route is a simple abstraction of Android's Intent class, but without any dependencies on the Android framework types.* Routes can be created with a set of parameters, just like a Bundle. Using Routes in presentation code makes it easy to unit test our navigation logic. The library also includes some extension methods for using Routes in an Activity class.

*Except for Parcelable.

Launching a Route from an Activity

class ExampleActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // create a route with parameters
        val route = Route.to(DestinationActivity::class.java)
            .param("foo", 123)
            .param("bar", true)
            .create()

        // then launch the route directly 
        startActivity(route)

        // or convert to an Intent 
        val intent = intentFor(route)
    }
}

Receiving parameters in an Activity

class DestinationActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // access params directly from the Intent
        val foo = intent?.extras?.getInt("foo")
        val bar = intent?.extras?.getBoolean("bar")

        // or use the withParams() extension
        withParams {
            val foo = getInt("foo")
            val bar = getBoolean("bar")
        }
    }
}

Testing navigation logic

This is an example of a top-level 'Route builder' function that returns a Route with two parameters.

fun createGreetingRoute(greeting: String, name: String): Route {
    return Route.to(GreetingActivity::class.java)
        .param("key_greeting", greeting)
        .param("key_name", name)
        .create()
}

And here's a test that checks the Route is created with the correct destination and parameters.

@Test 
fun `creates route for greeting page`() {    
    val result = createGreetingRoute("hello", "world")    
    
    // check the destination class
    assert(result.destination == GreetingActivity::class.java)    
    
    // check parameters individually    
    assert(result.params.getString("key_greeting") == "hello")    
    assert(result.params.getString("key_name") == "world")    
    
    // or check against a params object    
    val expected = Route.params()    
        .put("key_greeting", "hello")    
        .put("key_name", "world")    
        .create()    
    
     assert(result.params == expected) 
}  

Sample

You can find a more complete example of using Routes and testing them in the sample project.

Installing

Routes is available on JitPack. To include it in your project, add the following line to your build.gradle:

dependencies {
    implementation 'com.github.greghynds:routes:1.0.0'
}

Building

The project can be built by navigating to the root directory and running:

./gradlew clean build

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

Apache License 2.0