Skip to content

Commit

Permalink
Cover feature observable errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
Laimiux committed Sep 17, 2024
1 parent 693dacd commit fcfb123
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import com.instacart.formula.android.fakes.MainKey
import com.instacart.formula.android.events.FragmentLifecycleEvent
import com.instacart.formula.android.fakes.NoOpViewFactory
import io.reactivex.rxjava3.observers.TestObserver
import io.reactivex.rxjava3.subjects.PublishSubject
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Shadows
import java.lang.RuntimeException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -204,6 +204,53 @@ class FragmentStoreTest {
)
}

@Test fun `feature observable error emits on screen error and finishes`() {
val stateSubject = PublishSubject.create<Any>()

val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
return Feature(
state = stateSubject,
viewFactory = NoOpViewFactory(),
)
}
}
bind(featureFactory)
}

val screenErrors = mutableListOf<Pair<FragmentKey, Throwable>>()
val environment = FragmentEnvironment(
onScreenError = { key, error ->
screenErrors.add(key to error)
}
)
val observer = store.state(environment).test()
val fragmentId = FragmentId("", MainKey(1))
store.onLifecycleEffect(
FragmentLifecycleEvent.Added(fragmentId = fragmentId)
)
stateSubject.onNext("value")

val firstModel = observer.values().last().outputs[fragmentId]?.renderModel
assertThat(firstModel).isEqualTo("value")

// Emit error
val error = RuntimeException("error")
stateSubject.onError(error)

// Model didn't change
val secondModel = observer.values().last().outputs[fragmentId]?.renderModel
assertThat(secondModel).isEqualTo("value")

// Store observable didn't crash
observer.assertNoErrors()

assertThat(screenErrors).containsExactly(
fragmentId.key to error
)
}

private fun FragmentStore.toStates(): TestObserver<Map<FragmentKey, FragmentOutput>> {
return state(FragmentEnvironment())
.map { it.outputs.mapKeys { entry -> entry.key.key } }
Expand Down
3 changes: 3 additions & 0 deletions jacoco.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
# Should match with what we run in .github/workflows/build-workflow.yml
./gradlew clean
./gradlew :formula:test
./gradlew :formula-coroutines:test
./gradlew :formula-android:testRelease
./gradlew :formula-android-tests:testRelease
./gradlew :formula-test:test
./gradlew :formula-lint:build
./gradlew jacocoTestReportMerged
open build/reports/jacoco/index.html

0 comments on commit fcfb123

Please sign in to comment.