Skip to content

Commit

Permalink
Merge pull request #14 from mvarnagiris/single_select_item_behavior_t…
Browse files Browse the repository at this point in the history
…ests

Extracted tests to use in client.
  • Loading branch information
mvarnagiris authored Mar 12, 2018
2 parents 45821af + 58b2d26 commit 18edb37
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 77 deletions.
4 changes: 3 additions & 1 deletion src/main/kotlin/com/mvcoding/mvp/DataSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ package com.mvcoding.mvp

interface DataSource<DATA> {
fun data(): O<DATA>
}
}

fun <DATA> DataSource<DATA>.function(): () -> O<DATA> = { data() }
7 changes: 7 additions & 0 deletions src/main/kotlin/com/mvcoding/mvp/DataWriter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.mvcoding.mvp

interface DataWriter<in DATA> {
fun write(data: DATA)
}

fun <DATA> DataWriter<DATA>.function(): (DATA) -> Unit = { write(it) }
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.mvcoding.mvp.behaviors

import com.mvcoding.mvp.Behavior
import com.mvcoding.mvp.O
import com.mvcoding.mvp.Presenter
import com.mvcoding.mvp.RxSchedulers
import com.mvcoding.mvp.*
import com.mvcoding.mvp.behaviors.SingleSelectItemBehavior.SingleSelectState.*
import io.reactivex.rxkotlin.withLatestFrom

Expand All @@ -14,6 +11,14 @@ class SingleSelectItemBehavior<in ITEM, in VIEW : SingleSelectItemBehavior.View<
private val setSelectedItem: (ITEM) -> Unit,
private val schedulers: RxSchedulers) : Behavior<VIEW>() {

constructor(
item: ITEM,
noItem: ITEM,
selectedItemSource: DataSource<ITEM>,
selectedItemWriter: DataWriter<ITEM>,
schedulers: RxSchedulers) :
this(item, noItem, selectedItemSource.function(), selectedItemWriter.function(), schedulers)

override fun onViewAttached(view: VIEW) {
super.onViewAttached(view)

Expand Down
9 changes: 9 additions & 0 deletions src/main/kotlin/com/mvcoding/mvp/data/FunctionDataWriter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mvcoding.mvp.data

import com.mvcoding.mvp.DataWriter

class FunctionDataWriter<in DATA>(private val dataWriter: (DATA) -> Unit) : DataWriter<DATA> {
override fun write(data: DATA) = dataWriter(data)
}

fun <DATA> ((DATA) -> Unit).dataWriter() = FunctionDataWriter(this)
Original file line number Diff line number Diff line change
Expand Up @@ -2,120 +2,230 @@ package com.mvcoding.mvp.behaviors

import com.jakewharton.rxrelay2.PublishRelay
import com.mvcoding.mvp.O
import com.mvcoding.mvp.Presenter
import com.mvcoding.mvp.trampolines
import com.nhaarman.mockitokotlin2.*
import org.junit.Before
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import io.reactivex.Observable
import org.junit.Test

class SingleSelectItemBehaviorTest {

private val selectsRelay = PublishRelay.create<Unit>()

private val item = "item"
private val otherItem = "otherItem"
private val noItem = ""

private val getSelectedItem = mock<() -> O<String>>()
private val setSelectedItem = mock<(String) -> Unit>()
private val view = mock<SingleSelectItemBehavior.View<String>>()
private val behavior = SingleSelectItemBehavior(
item,
noItem,
getSelectedItem,
setSelectedItem,
trampolines)

@Before
fun setUp() {
whenever(view.selects()).thenReturn(selectsRelay)
}

@Test
fun `sets item selected after select when nothing was selected yet`() {
whenever(getSelectedItem()).thenReturn(O.just(noItem))
behavior attach view

select()

verify(setSelectedItem).invoke(item)
testSetsItemSelectedAfterSelectWhenNothingWasSelectedYet(item, noItem, createPresenter())
}

@Test
fun `sets item selected after select when other item is selected`() {
whenever(getSelectedItem()).thenReturn(O.just(otherItem))
behavior attach view

select()

verify(setSelectedItem).invoke(item)
fun `sets item selected after select when other item was selected`() {
testSetsItemSelectedAfterSelectWhenOtherItemWasSelected(item, otherItem, createPresenter())
}

@Test
fun `sets item not selected after select when this item was selected`() {
whenever(getSelectedItem()).thenReturn(O.just(item))
behavior attach view

select()

verify(setSelectedItem).invoke(noItem)
testSetsItemNotSelectedAfterSelectWhenThisItemWasSelected(item, noItem, createPresenter())
}

@Test
fun `sets item not selected on detach when this item was selected`() {
whenever(getSelectedItem()).thenReturn(O.just(item))

behavior attach view
behavior detach view

verify(setSelectedItem).invoke(noItem)
testSetsItemNotSelectedOnDetachWhenThisItemWasSelected(item, noItem, createPresenter())
}

@Test
fun `does not change select state on detach when other item was selected`() {
whenever(getSelectedItem()).thenReturn(O.just(otherItem))

behavior attach view
behavior detach view

verify(setSelectedItem, never()).invoke(any())
testDoesNotChangeSelectStateOnDetachWhenOtherItemWasSelected(otherItem, noItem, createPresenter())
}

@Test
fun `does not change select state on detach when nothing was selected`() {
whenever(getSelectedItem()).thenReturn(O.just(noItem))

behavior attach view
behavior detach view

verify(setSelectedItem, never()).invoke(any())
testDoesNotChangeSelectStateOnDetachWhenNothingWasSelected(noItem, createPresenter())
}

@Test
fun `shows nothing selected when nothing is selected`() {
whenever(getSelectedItem()).thenReturn(O.just(noItem))

behavior attach view

verify(view).showNothingSelected(item)
testShowsNothingSelectedWhenNothingIsSelected(item, noItem, createPresenter())
}

@Test
fun `shows other selected when other is selected`() {
whenever(getSelectedItem()).thenReturn(O.just(otherItem))

behavior attach view

verify(view).showOtherSelected(item, otherItem)
testShowsOtherSelectedWhenOtherItemIsSelected(item, otherItem, createPresenter())
}

@Test
fun `shows this selected when this is selected`() {
whenever(getSelectedItem()).thenReturn(O.just(item))

behavior attach view

verify(view).showThisSelected(item)
testShowsThisSelectedWhenThisItemIsSelected(item, createPresenter())
}

private fun select() = selectsRelay.accept(Unit)
private fun createPresenter(): (() -> O<String>, (String) -> Unit) -> SingleSelectItemBehavior<String, SingleSelectItemBehavior.View<String>> {
return { get, set -> SingleSelectItemBehavior(item, noItem, get, set, trampolines) }
}
}

inline fun <ITEM : Any, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testSingleSelectItemBehavior(
item: ITEM,
noItem: ITEM,
otherItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {

testSetsItemSelectedAfterSelectWhenNothingWasSelectedYet(item, noItem, createPresenter)
testSetsItemSelectedAfterSelectWhenOtherItemWasSelected(item, otherItem, createPresenter)
testSetsItemNotSelectedAfterSelectWhenThisItemWasSelected(item, noItem, createPresenter)
testSetsItemNotSelectedOnDetachWhenThisItemWasSelected(item, noItem, createPresenter)
testDoesNotChangeSelectStateOnDetachWhenOtherItemWasSelected(otherItem, noItem, createPresenter)
testDoesNotChangeSelectStateOnDetachWhenNothingWasSelected(noItem, createPresenter)
testShowsNothingSelectedWhenNothingIsSelected(item, noItem, createPresenter)
testShowsOtherSelectedWhenOtherItemIsSelected(item, otherItem, createPresenter)
testShowsThisSelectedWhenThisItemIsSelected(item, createPresenter)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testSetsItemSelectedAfterSelectWhenNothingWasSelectedYet(
item: ITEM,
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val selectsRelay = PublishRelay.create<Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(view.selects()).thenReturn(selectsRelay)
whenever(getSelectedItem()).thenReturn(O.just(noItem))
presenter attach view

selectsRelay.accept(Unit)

verify(setSelectedItem).invoke(item)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testSetsItemSelectedAfterSelectWhenOtherItemWasSelected(
item: ITEM,
otherItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val selectsRelay = PublishRelay.create<Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(view.selects()).thenReturn(selectsRelay)
whenever(getSelectedItem()).thenReturn(O.just(otherItem))
presenter attach view

selectsRelay.accept(Unit)

verify(setSelectedItem).invoke(item)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testSetsItemNotSelectedAfterSelectWhenThisItemWasSelected(
item: ITEM,
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val selectsRelay = PublishRelay.create<Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(view.selects()).thenReturn(selectsRelay)
whenever(getSelectedItem()).thenReturn(O.just(item))
presenter attach view

selectsRelay.accept(Unit)

verify(setSelectedItem).invoke(noItem)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testSetsItemNotSelectedOnDetachWhenThisItemWasSelected(
item: ITEM,
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(item))

presenter attach view
presenter detach view

verify(setSelectedItem).invoke(noItem)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testDoesNotChangeSelectStateOnDetachWhenOtherItemWasSelected(
otherItem: ITEM,
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(otherItem))

presenter attach view
presenter detach view

verify(setSelectedItem, never()).invoke(noItem)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testDoesNotChangeSelectStateOnDetachWhenNothingWasSelected(
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val setSelectedItem = mock<(ITEM) -> Unit>()
val presenter = createPresenter(getSelectedItem, setSelectedItem)
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(noItem))

presenter attach view
presenter detach view

verify(setSelectedItem, never()).invoke(noItem)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testShowsNothingSelectedWhenNothingIsSelected(
item: ITEM,
noItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val presenter = createPresenter(getSelectedItem, mock())
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(noItem))

presenter attach view

verify(view).showNothingSelected(item)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testShowsOtherSelectedWhenOtherItemIsSelected(
item: ITEM,
otherItem: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val presenter = createPresenter(getSelectedItem, mock())
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(otherItem))

presenter attach view

verify(view).showOtherSelected(item, otherItem)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> testShowsThisSelectedWhenThisItemIsSelected(
item: ITEM,
createPresenter: (() -> O<ITEM>, (ITEM) -> Unit) -> Presenter<VIEW>) {
val getSelectedItem = mock<() -> O<ITEM>>()
val presenter = createPresenter(getSelectedItem, mock())
val view = view<ITEM, VIEW>()
whenever(getSelectedItem()).thenReturn(O.just(item))

presenter attach view

verify(view).showThisSelected(item)
}

inline fun <ITEM, reified VIEW : SingleSelectItemBehavior.View<ITEM>> view(): VIEW = mock<VIEW>().apply {
whenever(selects()).thenReturn(Observable.never())
}

0 comments on commit 18edb37

Please sign in to comment.