fun handle(d : Data) fun showLoading( ) fun showError( ) fun doSomething( ) override fun handle(d : Data) override fun showLoading( ) override fun showError( ) doAnotherThing ( ) fun doAnotherThing( ) method call
) { fun states() = container.observableStates() fun consume(execution: StateTransition<T>) = executor.execute { wrapWithStates(execution) } // Continue on next slide }
the current state processed by the State Machine. The implementation is CoroutineScope-aware and uses a ConflatedBroadcastChannel as communication engine to propagate state to consumers. We can build a StateContainer instance with a CoroutineScope differente than the consumer’s scope
val f = object : ViewModelProvider.Factory { override fun <Model : ViewModel> create(klass: Class<Model>) = ConfigChangesAwareStateContainer<T>() as Model } val keyClazz = ConfigChangesAwareStateContainer()class.java return ViewModelProviders.of(host, f)[keyClazz] as StateContainer<T> } } }
remoteFacts = mock<RemoteFactsService>() private lateinit var usecase: FetchCategories private val categories = mutableListOf( RelatedCategory.Available("dev"), RelatedCategory.Available("code") ) @Before fun `before each test`() { usecase = FetchCategories(categoriesCache, remoteFacts) } @Test fun `should fetch from cache from available`() { runBlocking { `given that remote service not available`() `given that cache returns categories`() assertThat(usecase.execute()).isEqualTo(categories) } } }