// Path: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyData.java
// public class CurrencyData {
//     private final String mBaseCurrency;
//     private Date mDate;
//     private Map<String, Double> mCurrencies;
// 
//     public CurrencyData(final Date date, final Map<String, Double> currencies, final String baseCurrency) {
//         mDate = date;
//         mCurrencies = currencies;
//         mBaseCurrency = baseCurrency;
//     }
// 
//     public String getBaseCurrency() {
//         return mBaseCurrency;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public Map<String, Double> getCurrencies() {
//         return mCurrencies;
//     }
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/datasource/CurrencyDataSource.java
// public interface CurrencyDataSource {
// 
//     Observable<CurrencyData> getCurrencies(Date date);
// 
//     boolean containsCurrencyValue(Date date, String currencyCode);
// 
//     boolean containsCurrencyValues(Date date);
// 
//     Observable<SingleValue> getCurrencyValues(Date startDate, Date endDate, String currencyCode);
// 
//     void storeCurrencies(CurrencyData currencyData);
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/repository/CachingCurrencyRepository.java
// public class CachingCurrencyRepository implements CurrencyRepository {
//     private CurrencyDataSource mLocalSource;
//     private CurrencyDataSource mRemoteSource;
// 
//     public CachingCurrencyRepository(final CurrencyDataSource localSource,
//                                      final CurrencyDataSource remoteSource) {
//         mLocalSource = localSource;
//         mRemoteSource = remoteSource;
//     }
// 
//     @Override
//     public Observable<CurrencyData> getCurrencies(final Date date) {
//         if (mLocalSource.containsCurrencyValues(date)) {
//             return mLocalSource.getCurrencies(date);
//         }
//         final Observable<CurrencyData> remoteCurrencies = mRemoteSource.getCurrencies(date);
//         remoteCurrencies.doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData));
//         return remoteCurrencies;
//     }
// 
//     @Override
//     public Observable<SingleValue> getSeries(final Date from, final Date to, final String currencyCode) {
//         return Observable.create(emitter -> {
//             final Calendar calendar = Calendar.getInstance();
//             calendar.setTime(from);
// 
//             List<Observable<CurrencyData>> cloudRequestObservables = new ArrayList<>();
//             while (true) {
//                 final Date date = calendar.getTime();
//                 if (!mLocalSource.containsCurrencyValue(date, currencyCode)) {
//                     cloudRequestObservables.add(
//                             mRemoteSource.getCurrencies(date)
//                                     .doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData)));
//                 }
//                 calendar.add(Calendar.DAY_OF_YEAR, 1);
//                 if (calendar.getTimeInMillis() >= to.getTime()) {
//                     break;
//                 }
//             }
//             Observable.merge(cloudRequestObservables)
//                     .subscribeOn(Schedulers.io())
//                     .doOnComplete(() -> {
//                         mLocalSource.getCurrencyValues(from, to, currencyCode)
//                                 .doOnNext(emitter::onNext)
//                                 .doOnComplete(emitter::onComplete)
//                                 .subscribe();
//                     }).subscribe();
//         });
//     }
// }


import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.data.datasource.CurrencyDataSource;
import eu.rampsoftware.er.data.repository.CachingCurrencyRepository;
import io.reactivex.Observable;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
package eu.rampsoftware.er.data.data;





public class CachingCurrencyRepositoryTest {
    public static final long MILLIS_22_01_2016__10_00 = 1453453200000L;
    public static final long MILLIS_24_01_2016__10_00 = 1453593600000L;
    public static final long MILLIS_DAY = 24 * 3600 * 1000;
    @Mock
    CurrencyDataSource mLocalDataSource;
    @Mock
    CurrencyDataSource mRemoteDataSource;

    @Captor
    ArgumentCaptor<Date> mDateCaptor;

    @Captor
    ArgumentCaptor<CurrencyData> mCurrencyDataCaptor;

// Path: databoundary/src/main/java/eu/rampsoftware/er/data/CurrencyData.java
// public class CurrencyData {
//     private final String mBaseCurrency;
//     private Date mDate;
//     private Map<String, Double> mCurrencies;
// 
//     public CurrencyData(final Date date, final Map<String, Double> currencies, final String baseCurrency) {
//         mDate = date;
//         mCurrencies = currencies;
//         mBaseCurrency = baseCurrency;
//     }
// 
//     public String getBaseCurrency() {
//         return mBaseCurrency;
//     }
// 
//     public Date getDate() {
//         return mDate;
//     }
// 
//     public Map<String, Double> getCurrencies() {
//         return mCurrencies;
//     }
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/datasource/CurrencyDataSource.java
// public interface CurrencyDataSource {
// 
//     Observable<CurrencyData> getCurrencies(Date date);
// 
//     boolean containsCurrencyValue(Date date, String currencyCode);
// 
//     boolean containsCurrencyValues(Date date);
// 
//     Observable<SingleValue> getCurrencyValues(Date startDate, Date endDate, String currencyCode);
// 
//     void storeCurrencies(CurrencyData currencyData);
// }
// 
// Path: data/src/main/java/eu/rampsoftware/er/data/repository/CachingCurrencyRepository.java
// public class CachingCurrencyRepository implements CurrencyRepository {
//     private CurrencyDataSource mLocalSource;
//     private CurrencyDataSource mRemoteSource;
// 
//     public CachingCurrencyRepository(final CurrencyDataSource localSource,
//                                      final CurrencyDataSource remoteSource) {
//         mLocalSource = localSource;
//         mRemoteSource = remoteSource;
//     }
// 
//     @Override
//     public Observable<CurrencyData> getCurrencies(final Date date) {
//         if (mLocalSource.containsCurrencyValues(date)) {
//             return mLocalSource.getCurrencies(date);
//         }
//         final Observable<CurrencyData> remoteCurrencies = mRemoteSource.getCurrencies(date);
//         remoteCurrencies.doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData));
//         return remoteCurrencies;
//     }
// 
//     @Override
//     public Observable<SingleValue> getSeries(final Date from, final Date to, final String currencyCode) {
//         return Observable.create(emitter -> {
//             final Calendar calendar = Calendar.getInstance();
//             calendar.setTime(from);
// 
//             List<Observable<CurrencyData>> cloudRequestObservables = new ArrayList<>();
//             while (true) {
//                 final Date date = calendar.getTime();
//                 if (!mLocalSource.containsCurrencyValue(date, currencyCode)) {
//                     cloudRequestObservables.add(
//                             mRemoteSource.getCurrencies(date)
//                                     .doOnNext(currencyData -> mLocalSource.storeCurrencies(currencyData)));
//                 }
//                 calendar.add(Calendar.DAY_OF_YEAR, 1);
//                 if (calendar.getTimeInMillis() >= to.getTime()) {
//                     break;
//                 }
//             }
//             Observable.merge(cloudRequestObservables)
//                     .subscribeOn(Schedulers.io())
//                     .doOnComplete(() -> {
//                         mLocalSource.getCurrencyValues(from, to, currencyCode)
//                                 .doOnNext(emitter::onNext)
//                                 .doOnComplete(emitter::onComplete)
//                                 .subscribe();
//                     }).subscribe();
//         });
//     }
// }


// Path: data/src/test/java/eu/rampsoftware/er/data/data/CachingCurrencyRepositoryTest.java
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import eu.rampsoftware.er.data.CurrencyData;
import eu.rampsoftware.er.data.datasource.CurrencyDataSource;
import eu.rampsoftware.er.data.repository.CachingCurrencyRepository;
import io.reactivex.Observable;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

package eu.rampsoftware.er.data.data;





public class CachingCurrencyRepositoryTest {
    public static final long MILLIS_22_01_2016__10_00 = 1453453200000L;
    public static final long MILLIS_24_01_2016__10_00 = 1453593600000L;
    public static final long MILLIS_DAY = 24 * 3600 * 1000;
    @Mock
    CurrencyDataSource mLocalDataSource;
    @Mock
    CurrencyDataSource mRemoteDataSource;

    @Captor
    ArgumentCaptor<Date> mDateCaptor;

    @Captor
    ArgumentCaptor<CurrencyData> mCurrencyDataCaptor;

    private CachingCurrencyRepository mCurrencyRepository;