From c88e76da44205e573078f4a8b7a8d29b08c04d23 Mon Sep 17 00:00:00 2001 From: Laimonas Turauskas Date: Wed, 25 Sep 2024 12:53:09 -0400 Subject: [PATCH] Refactor FeatureFactory public API using Params. --- CHANGELOG.md | 1 + .../instacart/formula/TestFeatureFactory.kt | 5 ++-- .../formula/android/FeatureFactory.kt | 16 +++++++++++-- .../android/internal/MappedFeatureFactory.kt | 4 ++-- .../formula/android/FragmentStoreTest.kt | 24 +++++++++---------- .../stopwatch/StopwatchFeatureFactory.kt | 4 ++-- .../todoapp/tasks/TaskListFeatureFactory.kt | 4 ++-- .../testutils/android/NoOpFeatureFactory.kt | 4 ++-- 8 files changed, 37 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a45c37..23ea2797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - **Breaking**: Removed `FlowFactory` and `Flow` - **Breaking**: Replace `FragmentStoreBuilder` with `FeaturesBuilder` - **Breaking**: Rename `FragmentFlowStore` to `FragmentStore`, `FragmentState` to `FragmentOutput`, `FragmentFlowState` to `FragmentState` +- **Breaking**: Making `FeatureFactory` into an abstract class and modifying the `initialize` API to use `Params` wrapper type ## [0.7.1] - June 28, 2022 - **Breaking**: Rename `FragmentBindingBuilder` to `FragmentStoreBuilder` diff --git a/formula-android-tests/src/test/java/com/instacart/formula/TestFeatureFactory.kt b/formula-android-tests/src/test/java/com/instacart/formula/TestFeatureFactory.kt index c92f5ff4..7e680f88 100644 --- a/formula-android-tests/src/test/java/com/instacart/formula/TestFeatureFactory.kt +++ b/formula-android-tests/src/test/java/com/instacart/formula/TestFeatureFactory.kt @@ -9,9 +9,8 @@ import io.reactivex.rxjava3.core.Observable class TestFeatureFactory( private val render: (FragmentKey, Any) -> Unit = { _, _ -> }, private val state: (Key) -> Observable, - -) : FeatureFactory { - override fun initialize(dependencies: Unit, key: Key): Feature { +) : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = state(key), viewFactory = TestViewFactory { _, value -> diff --git a/formula-android/src/main/java/com/instacart/formula/android/FeatureFactory.kt b/formula-android/src/main/java/com/instacart/formula/android/FeatureFactory.kt index 08be315b..05402b84 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/FeatureFactory.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/FeatureFactory.kt @@ -35,10 +35,22 @@ package com.instacart.formula.android * @param Key a type of fragment key that is used to identify this feature. * */ -interface FeatureFactory { +abstract class FeatureFactory { + + inner class Params( + val dependencies: @UnsafeVariance Dependencies, + val key: @UnsafeVariance Key, + ) + + /** + * Initializes the [Feature] using [Params] provided. + */ + abstract fun Params.initialize(): Feature /** * Initializes state observable and a view factory for a specific [key]. */ - fun initialize(dependencies: Dependencies, key: Key): Feature + fun initialize(dependencies: Dependencies, key: Key): Feature { + return Params(dependencies, key).initialize() + } } diff --git a/formula-android/src/main/java/com/instacart/formula/android/internal/MappedFeatureFactory.kt b/formula-android/src/main/java/com/instacart/formula/android/internal/MappedFeatureFactory.kt index ca061e7c..e1f3efb4 100644 --- a/formula-android/src/main/java/com/instacart/formula/android/internal/MappedFeatureFactory.kt +++ b/formula-android/src/main/java/com/instacart/formula/android/internal/MappedFeatureFactory.kt @@ -8,8 +8,8 @@ import com.instacart.formula.android.FragmentKey internal class MappedFeatureFactory( private val delegate: FeatureFactory, private val toDependencies: (Component) -> Dependencies, -) : FeatureFactory { - override fun initialize(dependencies: Component, key: Key): Feature { +) : FeatureFactory() { + override fun Params.initialize(): Feature { return delegate.initialize( dependencies = toDependencies(dependencies), key = key, diff --git a/formula-android/src/test/java/com/instacart/formula/android/FragmentStoreTest.kt b/formula-android/src/test/java/com/instacart/formula/android/FragmentStoreTest.kt index 87bd3b09..69a8cd5a 100644 --- a/formula-android/src/test/java/com/instacart/formula/android/FragmentStoreTest.kt +++ b/formula-android/src/test/java/com/instacart/formula/android/FragmentStoreTest.kt @@ -87,8 +87,8 @@ class FragmentStoreTest { } @Test fun `bind feature factory with to dependencies defined`() { - val myFeatureFactory = object : FeatureFactory { - override fun initialize(dependencies: String, key: MainKey): Feature { + val myFeatureFactory = object : FeatureFactory() { + override fun Params.initialize(): Feature { return TestUtils.feature( stateValue = dependencies ) @@ -182,8 +182,8 @@ class FragmentStoreTest { @Test fun `store returns failure event when feature factory initialization throws an error`() { val expectedError = RuntimeException("something happened") val store = FragmentStore.init(FakeComponent()) { - val featureFactory = object : FeatureFactory { - override fun initialize(dependencies: FakeComponent, key: MainKey): Feature { + val featureFactory = object : FeatureFactory() { + override fun Params.initialize(): Feature { throw expectedError } } @@ -209,8 +209,8 @@ class FragmentStoreTest { val stateSubject = PublishSubject.create() val store = FragmentStore.init { - val featureFactory = object : FeatureFactory { - override fun initialize(dependencies: Any, key: MainKey): Feature { + val featureFactory = object : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = stateSubject, viewFactory = TestViewFactory(), @@ -248,8 +248,8 @@ class FragmentStoreTest { val stateSubject = PublishSubject.create() val store = FragmentStore.init { - val featureFactory = object : FeatureFactory { - override fun initialize(dependencies: Any, key: MainKey): Feature { + val featureFactory = object : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = stateSubject, viewFactory = TestViewFactory(), @@ -293,8 +293,8 @@ class FragmentStoreTest { @Test fun `fragment store visible output`() { val store = FragmentStore.init { - val featureFactory = object : FeatureFactory { - override fun initialize(dependencies: Any, key: MainKey): Feature { + val featureFactory = object : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = Observable.just("value"), viewFactory = TestViewFactory(), @@ -360,8 +360,8 @@ class FragmentStoreTest { private fun FragmentKey.asAddedEvent() = FragmentLifecycleEvent.Added(FragmentId("", this)) private fun FragmentKey.asRemovedEvent() = FragmentLifecycleEvent.Removed(FragmentId("", this)) - class TestFeatureFactory: FeatureFactory { - override fun initialize(dependencies: FakeComponent, key: FragmentKeyT): Feature { + class TestFeatureFactory: FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = dependencies.state(key), viewFactory = TestViewFactory() diff --git a/samples/stopwatch-compose/src/main/java/com/instacart/formula/compose/stopwatch/StopwatchFeatureFactory.kt b/samples/stopwatch-compose/src/main/java/com/instacart/formula/compose/stopwatch/StopwatchFeatureFactory.kt index bfde16c0..b7b60d6d 100644 --- a/samples/stopwatch-compose/src/main/java/com/instacart/formula/compose/stopwatch/StopwatchFeatureFactory.kt +++ b/samples/stopwatch-compose/src/main/java/com/instacart/formula/compose/stopwatch/StopwatchFeatureFactory.kt @@ -23,8 +23,8 @@ import com.instacart.formula.android.compose.ComposeViewFactory import com.instacart.formula.invoke import com.instacart.formula.rxjava3.toObservable -class StopwatchFeatureFactory : FeatureFactory { - override fun initialize(dependencies: Any, key: StopwatchKey): Feature { +class StopwatchFeatureFactory : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = StopwatchFormula().toObservable(), viewFactory = StopwatchViewFactory() diff --git a/samples/todoapp/src/main/java/com/examples/todoapp/tasks/TaskListFeatureFactory.kt b/samples/todoapp/src/main/java/com/examples/todoapp/tasks/TaskListFeatureFactory.kt index 4fca63fd..510aae38 100644 --- a/samples/todoapp/src/main/java/com/examples/todoapp/tasks/TaskListFeatureFactory.kt +++ b/samples/todoapp/src/main/java/com/examples/todoapp/tasks/TaskListFeatureFactory.kt @@ -9,13 +9,13 @@ import com.instacart.formula.android.LayoutViewFactory import com.instacart.formula.android.ViewInstance import com.instacart.formula.rxjava3.toObservable -class TaskListFeatureFactory : FeatureFactory { +class TaskListFeatureFactory : FeatureFactory() { interface Dependencies { fun taskRepo(): TaskRepo fun taskListInput(): TaskListFormula.Input } - override fun initialize(dependencies: Dependencies, key: TaskListKey): Feature { + override fun Params.initialize(): Feature { // Note: we could create our own internal dagger component here using the dependencies. val formula = TaskListFormula(dependencies.taskRepo()) return Feature( diff --git a/test-utils/android/src/main/java/com/instacart/testutils/android/NoOpFeatureFactory.kt b/test-utils/android/src/main/java/com/instacart/testutils/android/NoOpFeatureFactory.kt index eeafd912..5066aea8 100644 --- a/test-utils/android/src/main/java/com/instacart/testutils/android/NoOpFeatureFactory.kt +++ b/test-utils/android/src/main/java/com/instacart/testutils/android/NoOpFeatureFactory.kt @@ -8,8 +8,8 @@ import io.reactivex.rxjava3.core.Observable class NoOpFeatureFactory( private val viewFactory: ViewFactory = TestViewFactory(), -) : FeatureFactory { - override fun initialize(dependencies: Unit, key: FragmentKeyT): Feature { +) : FeatureFactory() { + override fun Params.initialize(): Feature { return Feature( state = Observable.empty(), viewFactory = viewFactory,