diff --git a/src/main/kotlin/com/mvcoding/mvp/Behavior.kt b/src/main/kotlin/com/mvcoding/mvp/Behavior.kt new file mode 100644 index 0000000..3d0b351 --- /dev/null +++ b/src/main/kotlin/com/mvcoding/mvp/Behavior.kt @@ -0,0 +1,3 @@ +package com.mvcoding.mvp + +abstract class Behavior : Presenter() \ No newline at end of file diff --git a/src/main/kotlin/com/mvcoding/mvp/Presenter.kt b/src/main/kotlin/com/mvcoding/mvp/Presenter.kt index 253c50e..0260880 100644 --- a/src/main/kotlin/com/mvcoding/mvp/Presenter.kt +++ b/src/main/kotlin/com/mvcoding/mvp/Presenter.kt @@ -7,7 +7,7 @@ import io.reactivex.Single import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable -abstract class Presenter { +abstract class Presenter(private vararg val behaviors: Behavior) { private lateinit var compositeDisposable: CompositeDisposable private var view: View? = null @@ -15,6 +15,7 @@ abstract class Presenter { ensureViewIsNotAttached(view) this.view = view this.compositeDisposable = CompositeDisposable() + behaviors.forEach { it attach view } onViewAttached(view) } @@ -22,6 +23,7 @@ abstract class Presenter { ensureGivenViewIsAttached(view) this.view = null this.compositeDisposable.dispose() + behaviors.forEach { it detach view } onViewDetached(view) } @@ -47,17 +49,22 @@ abstract class Presenter { protected fun Observable.subscribeUntilDetached(onNext: (T) -> Unit, onError: (Throwable) -> Unit): Disposable = subscribe(onNext, onError).apply { disposeOnDetach(this) } + protected fun Flowable.subscribeUntilDetached(onNext: (T) -> Unit, onError: (Throwable) -> Unit): Disposable = subscribe(onNext, onError).apply { disposeOnDetach(this) } + protected fun Single.subscribeUntilDetached(onSuccess: (T) -> Unit, onError: (Throwable) -> Unit): Disposable = subscribe(onSuccess, onError).apply { disposeOnDetach(this) } + protected fun Maybe.subscribeUntilDetached(onSuccess: (T) -> Unit, onError: (Throwable) -> Unit): Disposable = subscribe(onSuccess, onError).apply { disposeOnDetach(this) } protected fun Observable.subscribeUntilDetached(onNext: (T) -> Unit, onError: (Throwable) -> Unit, onComplete: () -> Unit): Disposable = subscribe(onNext, onError, onComplete).apply { disposeOnDetach(this) } + protected fun Flowable.subscribeUntilDetached(onNext: (T) -> Unit, onError: (Throwable) -> Unit, onComplete: () -> Unit): Disposable = subscribe(onNext, onError, onComplete).apply { disposeOnDetach(this) } + protected fun Maybe.subscribeUntilDetached(onSuccess: (T) -> Unit, onError: (Throwable) -> Unit, onComplete: () -> Unit): Disposable = subscribe(onSuccess, onError, onComplete).apply { disposeOnDetach(this) } diff --git a/src/test/kotlin/com/mvcoding/mvp/PresenterTest.kt b/src/test/kotlin/com/mvcoding/mvp/PresenterTest.kt index 425fda0..ffa7a11 100644 --- a/src/test/kotlin/com/mvcoding/mvp/PresenterTest.kt +++ b/src/test/kotlin/com/mvcoding/mvp/PresenterTest.kt @@ -4,10 +4,12 @@ import com.memoizr.assertk.expect import com.memoizr.assertk.isInstance import com.memoizr.assertk.of import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.whenever import io.reactivex.* import org.junit.Before import org.junit.Test +import javax.xml.stream.FactoryConfigurationError import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -190,6 +192,21 @@ class PresenterTest { assertTrue { maybeOnNextOnErrorOnCompleteIsDisposed } } + @Test + fun `when presenter is attached-detached it attaches-detaches all behaviors`() { + val behavior1 = BehaviorForTest() + val behavior2 = BehaviorForTest() + val presenter = PresenterForTest(behavior1, behavior2) + + presenter attach viewForTest + behavior1.isAttached = true + behavior2.isAttached = true + + presenter detach viewForTest + behavior1.isAttached = false + behavior2.isAttached = false + } + interface ViewForTest : Presenter.View { fun observable(): Observable fun observableOnNext(): Observable @@ -208,7 +225,7 @@ class PresenterTest { fun maybeOnSuccessOnErrorOnComplete(): Maybe } - class PresenterForTest : Presenter() { + class PresenterForTest(vararg behavior: Behavior) : Presenter(*behavior) { override fun onViewAttached(view: ViewForTest) { super.onViewAttached(view) view.observable().subscribeUntilDetached() @@ -228,4 +245,18 @@ class PresenterTest { view.maybeOnSuccessOnErrorOnComplete().subscribeUntilDetached() } } + + class BehaviorForTest : Behavior() { + var isAttached = false + + override fun onViewAttached(view: ViewForTest) { + super.onViewAttached(view) + isAttached = true + } + + override fun onViewDetached(view: ViewForTest) { + super.onViewDetached(view) + isAttached = false + } + } } \ No newline at end of file