// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/behaviours/HideAtStartShowAtError.java
// public class HideAtStartShowAtError<T> implements FlowableTransformer<T, T> {
// 
//     private Action whenStart;
//     private Action atError;
//     private ErrorPredicate errorPredicate;
//     private Scheduler targetScheduler;
// 
//     public HideAtStartShowAtError(Action whenStart,
//                                   Action atError,
//                                   ErrorPredicate errorPredicate,
//                                   Scheduler targetScheduler) {
// 
//         this.whenStart = whenStart;
//         this.atError = atError;
//         this.errorPredicate = errorPredicate;
//         this.targetScheduler = targetScheduler;
//     }
// 
//     @Override public Publisher<T> apply(Flowable<T> upstream) {
//         return upstream
//                 .doOnSubscribe(subscription -> hide())
//                 .doOnError(this::evaluateAndShowIfApplicable);
//     }
// 
//     private void evaluateAndShowIfApplicable(Throwable throwable) {
//         if (errorPredicate.evaluate(throwable)) {
//             subscribeAndFireAction(atError);
//         }
//     }
// 
//     private void hide() {
//         subscribeAndFireAction(whenStart);
//     }
// 
//     private void subscribeAndFireAction(Action toPerform) {
//         Completable.fromAction(toPerform)
//                 .subscribeOn(targetScheduler)
//                 .subscribe();
//     }
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/util/ErrorPredicate.java
// public interface ErrorPredicate {
// 
//     boolean evaluate(Throwable error);
// 
// }
// 
// Path: app/src/test/java/br/ufs/demos/rxmvp/playground/util/MockitoHelpers.java
// public static VerificationMode oneTimeOnly() {
//     return VerificationModeFactory.times(1);
// }


import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import br.ufs.demos.rxmvp.playground.core.behaviours.HideAtStartShowAtError;
import br.ufs.demos.rxmvp.playground.util.ErrorPredicate;
import io.reactivex.Flowable;
import io.reactivex.Scheduler;
import io.reactivex.functions.Action;
import io.reactivex.schedulers.Schedulers;
import static br.ufs.demos.rxmvp.playground.util.MockitoHelpers.oneTimeOnly;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
package br.ufs.demos.rxmvp.playground.core;




/**
 * Created by bira on 6/30/17.
 */

@RunWith(MockitoJUnitRunner.class)
public class HideAtStartShowAtErrorTests {

    Scheduler scheduler = Schedulers.trampoline();
    ErrorPredicate positive = error -> true;
    ErrorPredicate negative = error -> false;

    @Mock Action whenStart;
    @Mock Action atError;

    @Before public void beforeEachTest() {
        MockitoAnnotations.initMocks(this);
    }

    @Test public void shouldHideAtStart_AndNotShowError_WhenFlowEmmits() throws Exception {
        Flowable.just("A", "B", "C")
                .compose(new HideAtStartShowAtError<>(whenStart, atError, positive, scheduler))
                .subscribe();

        verify(whenStart, oneTimeOnly()).run();
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/core/behaviours/HideAtStartShowAtError.java
// public class HideAtStartShowAtError<T> implements FlowableTransformer<T, T> {
// 
//     private Action whenStart;
//     private Action atError;
//     private ErrorPredicate errorPredicate;
//     private Scheduler targetScheduler;
// 
//     public HideAtStartShowAtError(Action whenStart,
//                                   Action atError,
//                                   ErrorPredicate errorPredicate,
//                                   Scheduler targetScheduler) {
// 
//         this.whenStart = whenStart;
//         this.atError = atError;
//         this.errorPredicate = errorPredicate;
//         this.targetScheduler = targetScheduler;
//     }
// 
//     @Override public Publisher<T> apply(Flowable<T> upstream) {
//         return upstream
//                 .doOnSubscribe(subscription -> hide())
//                 .doOnError(this::evaluateAndShowIfApplicable);
//     }
// 
//     private void evaluateAndShowIfApplicable(Throwable throwable) {
//         if (errorPredicate.evaluate(throwable)) {
//             subscribeAndFireAction(atError);
//         }
//     }
// 
//     private void hide() {
//         subscribeAndFireAction(whenStart);
//     }
// 
//     private void subscribeAndFireAction(Action toPerform) {
//         Completable.fromAction(toPerform)
//                 .subscribeOn(targetScheduler)
//                 .subscribe();
//     }
// 
// }
// 
// Path: app/src/main/java/br/ufs/demos/rxmvp/playground/util/ErrorPredicate.java
// public interface ErrorPredicate {
// 
//     boolean evaluate(Throwable error);
// 
// }
// 
// Path: app/src/test/java/br/ufs/demos/rxmvp/playground/util/MockitoHelpers.java
// public static VerificationMode oneTimeOnly() {
//     return VerificationModeFactory.times(1);
// }


// Path: app/src/test/java/br/ufs/demos/rxmvp/playground/core/HideAtStartShowAtErrorTests.java
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import br.ufs.demos.rxmvp.playground.core.behaviours.HideAtStartShowAtError;
import br.ufs.demos.rxmvp.playground.util.ErrorPredicate;
import io.reactivex.Flowable;
import io.reactivex.Scheduler;
import io.reactivex.functions.Action;
import io.reactivex.schedulers.Schedulers;
import static br.ufs.demos.rxmvp.playground.util.MockitoHelpers.oneTimeOnly;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

package br.ufs.demos.rxmvp.playground.core;




/**
 * Created by bira on 6/30/17.
 */

@RunWith(MockitoJUnitRunner.class)
public class HideAtStartShowAtErrorTests {

    Scheduler scheduler = Schedulers.trampoline();
    ErrorPredicate positive = error -> true;
    ErrorPredicate negative = error -> false;

    @Mock Action whenStart;
    @Mock Action atError;

    @Before public void beforeEachTest() {
        MockitoAnnotations.initMocks(this);
    }

    @Test public void shouldHideAtStart_AndNotShowError_WhenFlowEmmits() throws Exception {
        Flowable.just("A", "B", "C")
                .compose(new HideAtStartShowAtError<>(whenStart, atError, positive, scheduler))
                .subscribe();

        verify(whenStart, oneTimeOnly()).run();
        verifyZeroInteractions(atError);