Skip to content

Commit

Permalink
Add the RxImagePickerProfessor class test code.
Browse files Browse the repository at this point in the history
  • Loading branch information
qingmei2 committed Jan 23, 2018
1 parent 6b1e07e commit 8b9aac7
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import android.content.Context;
import android.net.Uri;
import android.support.annotation.VisibleForTesting;

import com.qingmei2.rximagepicker.config.RxImagePickerConfigProvider;
import com.qingmei2.rximagepicker.di.scheduler.IRxImagePickerSchedulers;
Expand All @@ -20,10 +21,14 @@
public final class RxImagePickerProcessor implements
IRxImagePickerProcessor {

private final Context context;
private final ICameraPickerView cameraPickerView;
private final IGalleryPickerView galleryPickerView;
private final IRxImagePickerSchedulers schedulers;
@VisibleForTesting
public final Context context;
@VisibleForTesting
public final ICameraPickerView cameraPickerView;
@VisibleForTesting
public final IGalleryPickerView galleryPickerView;
@VisibleForTesting
public final IRxImagePickerSchedulers schedulers;

public RxImagePickerProcessor(Context context,
ICameraPickerView cameraPickerView,
Expand All @@ -38,21 +43,35 @@ public RxImagePickerProcessor(Context context,
@Override
public Observable<?> process(RxImagePickerConfigProvider configProvider) {
return Observable.just(configProvider)
.flatMap(new Function<RxImagePickerConfigProvider, ObservableSource<Uri>>() {
@Override
public ObservableSource<Uri> apply(RxImagePickerConfigProvider provider) throws Exception {
switch (provider.getSourcesFrom()) {
case GALLERY:
return galleryPickerView.pickImage();
case CAMERA:
return cameraPickerView.takePhoto();
default:
throw new IllegalArgumentException("unknown SourceFrom data.");
}
}
})
.flatMap(new FuntionObserverAsConverter(configProvider.getObserverAs(), context))
.flatMap(sourceFrom(cameraPickerView, galleryPickerView))
.flatMap(observerAs(configProvider, context))
.subscribeOn(schedulers.io())
.observeOn(schedulers.ui());
}

@VisibleForTesting
public Function<RxImagePickerConfigProvider, ObservableSource<Uri>> sourceFrom(
ICameraPickerView cameraPickerView,
IGalleryPickerView galleryPickerView) {
return new Function<RxImagePickerConfigProvider, ObservableSource<Uri>>() {
@Override
public ObservableSource<Uri> apply(RxImagePickerConfigProvider provider) throws Exception {
switch (provider.getSourcesFrom()) {
case GALLERY:
return galleryPickerView.pickImage();
case CAMERA:
return cameraPickerView.takePhoto();
default:
throw new IllegalArgumentException("unknown SourceFrom data.");
}
}
};
}

@VisibleForTesting
public Function<Uri, ObservableSource<?>> observerAs(
RxImagePickerConfigProvider configProvider,
Context context) {
return new FuntionObserverAsConverter(configProvider.getObserverAs(), context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.VisibleForTesting;
import android.util.Log;

import com.qingmei2.rximagepicker.config.observeras.ObserverAs;
Expand All @@ -26,8 +27,10 @@ public final class FuntionObserverAsConverter implements Function<Uri, Observabl

private static final String TAG = "FuntionObserverAs";

private final ObserverAs observerAs;
private final Context context;
@VisibleForTesting
public final ObserverAs observerAs;
@VisibleForTesting
public final Context context;

public FuntionObserverAsConverter(ObserverAs observerAs,
Context context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.qingmei2.rximagepicker.core

import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import com.nhaarman.mockito_kotlin.*
import com.qingmei2.rximagepicker.config.RxImagePickerConfigProvider
import com.qingmei2.rximagepicker.config.observeras.ObserverAs
import com.qingmei2.rximagepicker.config.sources.SourcesFrom
import com.qingmei2.rximagepicker.di.scheduler.RxImagePickerTestSchedulers
import com.qingmei2.rximagepicker.funtions.FuntionObserverAsConverter
import com.qingmei2.rximagepicker.rule.TestSchedulerRule
import com.qingmei2.rximagepicker.ui.ICameraPickerView
import com.qingmei2.rximagepicker.ui.IGalleryPickerView
import io.reactivex.Observable
import io.reactivex.ObservableSource
import io.reactivex.functions.Function
import io.reactivex.observers.TestObserver
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentCaptor

class RxImagePickerProcessorTest {

@Rule
@JvmField
val rxRule = TestSchedulerRule()

private val mockContext: Context = mock()
private val mockCameraPickerView: ICameraPickerView = mock()
private val mockGalleryPickerView: IGalleryPickerView = mock()
private val schedulers = RxImagePickerTestSchedulers()

private val mockUri: Uri = mock()
private val mockUri2: Uri = mock()
private val mockBitmap: Bitmap = mock()

lateinit var processor: RxImagePickerProcessor

@Before
fun setUp() {
processor = RxImagePickerProcessor(mockContext,
mockCameraPickerView,
mockGalleryPickerView,
schedulers)
}

@Test
fun sourceFromTestCamera() {
whenever(mockCameraPickerView.takePhoto()).thenReturn(Observable.just(mockUri))

val observable = processor.sourceFrom(processor.cameraPickerView, processor.galleryPickerView)
.apply(instanceProvider(SourcesFrom.CAMERA)) as Observable<Uri>

verify(processor.cameraPickerView, times(1)).takePhoto()
verify(processor.galleryPickerView, never()).pickImage()
observable.test()
.assertComplete()
.assertNoErrors()
.assertValueCount(1)
.assertValueAt(0, mockUri)
}

@Test
fun sourceFromTestGallery() {
whenever(mockGalleryPickerView.pickImage()).thenReturn(Observable.just(mockUri))

val observable = processor.sourceFrom(processor.cameraPickerView, processor.galleryPickerView)
.apply(instanceProvider(SourcesFrom.GALLERY)) as Observable<Uri>

verify(processor.cameraPickerView, never()).takePhoto()
verify(processor.galleryPickerView, times(1)).pickImage()
observable.test()
.assertComplete()
.assertNoErrors()
.assertValueCount(1)
.assertValueAt(0, mockUri)
}

@Test
fun sourceFromTestFailed() {
// val sourceFrom: SourcesFrom = SourcesFrom.valueOf("123")
// val observable = processor.sourceFrom(processor.cameraPickerView, processor.galleryPickerView)
// .apply(instanceProvider(sourceFrom)) as Observable<Uri>
//
// observable.test()
// .assertNotComplete()
// .assertError(IllegalArgumentException::class.java)
//
// verify(processor.cameraPickerView, never()).takePhoto()
// verify(processor.galleryPickerView, never()).pickImage()
}

@Test
fun observerAsTest() {
val provider = instanceProvider()
val function = processor.observerAs(provider, processor.context) as FuntionObserverAsConverter

assertEquals(function.context, processor.context)
assertEquals(function.observerAs, provider.observerAs)
}

@Test
fun testProcessCameraAndUri() {
val spy = processor.let { spy(it) }
val configProvider = instanceProvider()

doReturn(testSourceFrom())
.whenever(spy).sourceFrom(mockCameraPickerView, mockGalleryPickerView)
doReturn(testObserverAsUri())
.whenever(spy).observerAs(configProvider, mockContext)

val value: Observable<Uri> = spy.process(configProvider) as Observable<Uri>

TestObserver<Uri>().apply {
value.subscribe(this)
rxRule.triggerActions()

assertComplete()
.assertNoErrors()
.assertValueCount(1)
.assertValueAt(0, mockUri2)
}
}

@Test
fun testProcessGalleryAndBitmap() {
val spy = processor.let { spy(it) }
val configProvider = instanceProvider()

doReturn(testSourceFrom())
.whenever(spy).sourceFrom(mockCameraPickerView, mockGalleryPickerView)
doReturn(testObserverAsbBitmap())
.whenever(spy).observerAs(configProvider, mockContext)

val value: Observable<Bitmap> = spy.process(configProvider) as Observable<Bitmap>

TestObserver<Bitmap>().apply {
value.subscribe(this)
rxRule.triggerActions()

assertComplete()
.assertNoErrors()
.assertValueCount(1)
.assertValueAt(0, mockBitmap)
}
}

private fun instanceProvider(sourcesFrom: SourcesFrom = SourcesFrom.CAMERA,
observerAs: ObserverAs = ObserverAs.URI)
: RxImagePickerConfigProvider {
return RxImagePickerConfigProvider(sourcesFrom, observerAs)
}

private fun testSourceFrom(): Function<RxImagePickerConfigProvider, ObservableSource<Uri>> {
return Function { provider -> Observable.just(mockUri) }
}

private fun testObserverAsUri(): Function<Uri, ObservableSource<Any>> {
return Function { uri -> Observable.just(mockUri2) }
}

private fun testObserverAsbBitmap(): Function<Uri, ObservableSource<Any>> {
return Function { uri -> Observable.just(mockBitmap) }
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package com.qingmei2.rximagepicker.mock

import android.graphics.Bitmap
import android.net.Uri
import com.qingmei2.rximagepicker.config.observeras.AsBitmap
import com.qingmei2.rximagepicker.config.observeras.AsUri
import com.qingmei2.rximagepicker.config.sources.Camera
import com.qingmei2.rximagepicker.config.sources.Gallery
import io.reactivex.Observable

interface TestImagePicker {

@Camera
fun camera()
@AsUri
fun camera(): Observable<Uri>

@Gallery
fun gallery()
@AsBitmap
fun gallery(): Observable<Bitmap>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.qingmei2.rximagepicker.rule

import io.reactivex.plugins.RxJavaPlugins
import io.reactivex.schedulers.TestScheduler
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import java.util.concurrent.TimeUnit

class TestSchedulerRule : TestRule {

private var testScheduler: TestScheduler = TestScheduler()

override fun apply(base: Statement?, description: Description?): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
RxJavaPlugins.setIoSchedulerHandler { testScheduler }
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
RxJavaPlugins.setNewThreadSchedulerHandler { testScheduler }
RxJavaPlugins.setSingleSchedulerHandler { testScheduler }
try {
base?.evaluate()
} finally {
RxJavaPlugins.reset()
}
}
}
}

fun advanceTimeTo(delayTime: Long, timeUnit: TimeUnit) {
testScheduler.advanceTimeTo(delayTime, timeUnit)
}

fun advanceTimeBy(delayTime: Long, timeUnit: TimeUnit) {
testScheduler.advanceTimeBy(delayTime, timeUnit)
}

fun triggerActions() {
testScheduler.triggerActions()
}

fun getScheduler(): TestScheduler {
return testScheduler
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-maker-inline

0 comments on commit 8b9aac7

Please sign in to comment.