Skip to content

Latest commit

History

History
113 lines (82 loc) 路 2.52 KB

start.md

File metadata and controls

113 lines (82 loc) 路 2.52 KB

Uniflow 馃- Simple Unidirectionnel Data Flow for Android & Kotlin

Getting Started 馃殌

Turn on Logging

At your Android Application start, just turn on Logging:

UniFlowLogger.init(AndroidMessageLogger())

Writing your first UI state

Let's describe our data state with UIState type:

data class WeatherState(val day : String, val temperature : String) : UIState()

Let's push a new state from our ViewModel:

class WeatherDataFlow(val repo : WeatherRepository) : AndroidDataFlow(defaultState = Empty) {
    
    // Uniflow Action
    fun getWeather() = action {
        // call to get data
        val weather = repo.getWeatherForToday().await()
        // return a new state
        setState { WeatherState(weather.day, weather.temperature) }
    }
}

On our UI, let's observe our incoming states:

class WeatherActivity : AppCompatActivity { 
    
    val weatherViewModel : WeatherDataFlow // ViewModel created with Koin for example :)
	
    override fun onCreate(savedInstanceState: Bundle?) {	
        
        // Observe incoming states
        onStates(weatherFlow) { state ->
            when (state) {
                // react on WeatherState update
                is WeatherState -> showWeather(state)
            }
        }
    }
}

Easy to test

Let's create our ViewModel instance and mock your states observer:

// Mocked repository
val mockedRepo : WeatherRepository = mockk(relaxed = true)
// Our DataFlow ViewModel
lateinit var dataFlow : WeatherDataFlow

@Before
fun before() {
    // create WeatherDataFlow instance with mocked WeatherRepository
    dataFlow = WeatherDataFlow(mockedRepo)
    // create test observer 
    view = detailViewModel.createTestObserver()
}

Don't forget to setup your test dispatcher:

// For Android ViewModel Test
@get:Rule
val rule = InstantTaskExecutorRule()

// Uniflow Test Dispatcher
@get:Rule
val testDispatcherRule = UniflowTestDispatchersRule()

Now we can test incoming states & events with assertReceived:

@Test
fun `has some weather`() {
    // prepare test data
    val weatherData = WeatherData()
    // setup mocked call
    coEvery { mockedRepo.getWeatherForToday() } willReturn { weatherData }
    
    // Call getWeather()
    dataFlow.getWeather()
        
    // verify state
    dataFlow.verifySequence(
        UIState.Empty,
        WeatherState(weatherData.day, weatherData.temperature)
    )
}