/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.datasource; import org.robolectric.RobolectricTestRunner; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import static com.facebook.datasource.DataSourceTestUtils.*; import static org.mockito.Mockito.*; /** * Tests for IncreasingQualityDataSourceSupplier */ @RunWith(RobolectricTestRunner.class) public class IncreasingQualityDataSourceSupplierTest extends AbstractDataSourceSupplier { @Before public void setUp() { super.setUp(); mDataSourceSupplier = IncreasingQualityDataSourceSupplier.create(mSuppliers); } /** * All data sources failed, highest-quality failed last, no intermediate results. */ @Test public void testLifecycle_F2_F3_F1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); setState(mSrc2, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, mock(Throwable.class)); subscriber2.onFailure(mSrc2); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); setState(mSrc3, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, mock(Throwable.class)); subscriber3.onFailure(mSrc3); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc3, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); Throwable throwable = mock(Throwable.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); subscriber1.onFailure(mSrc1); mInOrder.verify(mSrc1).close(); verifySubscriber(dataSource, mSrc1, ON_FAILURE); verifyState(dataSource, null, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); testClose(dataSource); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); } /** * Highest-quality data source failed second, result of the third data source is ignored. */ @Test public void testLifecycle_F2_F1_S3_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); setState(mSrc2, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, mock(Throwable.class)); subscriber2.onFailure(mSrc2); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); Throwable throwable = mock(Throwable.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); subscriber1.onFailure(mSrc1); mInOrder.verify(mSrc1).close(); verifySubscriber(dataSource, mSrc1, ON_FAILURE); verifyState(dataSource, null, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); // gets ignored because DS1 failed setState(mSrc3, NOT_CLOSED, FINISHED, WITH_RESULT, mock(Object.class), NOT_FAILED, null); subscriber3.onFailure(mSrc3); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc3, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); testClose(dataSource); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); } /** * Highest-quality data source failed, result of the third data source is ignored. * Second data source produced intermediate result first, the result is preserved until closed. */ @Test public void testLifecycle_I2_F2_F1_S3_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val2 = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2, NOT_FAILED, null); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2, FAILED, mock(Throwable.class)); subscriber2.onFailure(mSrc2); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2, NOT_FAILED, null); Throwable throwable = mock(Throwable.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); subscriber1.onFailure(mSrc1); mInOrder.verify(mSrc1).close(); verifySubscriber(dataSource, mSrc1, ON_FAILURE); verifyState(dataSource, mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2, FAILED, throwable); // gets ignored because DS1 failed // besides, this data source shouldn't have finished as it was supposed to be closed! setState(mSrc3, NOT_CLOSED, FINISHED, WITH_RESULT, mock(Object.class), NOT_FAILED, null); subscriber3.onFailure(mSrc3); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc3, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2, FAILED, throwable); testClose(dataSource, mSrc2); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, FAILED, throwable); } /** * Second data source produced multiple intermediate results first, intermediate result of * highest-quality data source gets ignored afterwards. Second data source fails and first data * source produced another intermediate result, but it gets ignored again. Finally, first data * source produced its final result which is set. */ @Test public void testLifecycle_I2_I2_I1_F2_I1_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val2a = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); Object val2b = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); // gets ignored because DS2 was first to produce result Object val1a = mock(Object.class); setState(mSrc1, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val1a, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); verifySubscriber(dataSource, mSrc1, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2b, FAILED, mock(Throwable.class)); subscriber2.onFailure(mSrc2); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); // gets ignored because DS2 was first to produce result Object val1b = mock(Object.class); setState(mSrc1, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); verifySubscriber(dataSource, mSrc1, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); Object val1c = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1c, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1c, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Interleaved results. */ @Test public void testLifecycle_I3_I2_I3_S2_I1_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val3a = mock(Object.class); setState(mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3a, NOT_FAILED, null); subscriber3.onNewResult(mSrc3); verifySubscriber(dataSource, mSrc3, ON_NEW_RESULT); verifyState(dataSource, mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3a, NOT_FAILED, null); // gets ignored because DS3 was first Object val2a = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3a, NOT_FAILED, null); Object val3b = mock(Object.class); setState(mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3b, NOT_FAILED, null); subscriber3.onNewResult(mSrc3); verifySubscriber(dataSource, mSrc3, ON_NEW_RESULT); verifyState(dataSource, mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3b, NOT_FAILED, null); Object val2b = mock(Object.class); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); // gets ignored because DS2 was first Object val1a = mock(Object.class); setState(mSrc1, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val1a, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); verifySubscriber(dataSource, mSrc1, NO_INTERACTIONS); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); Object val1b = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Second data source produced its final result, followed by the first data source. */ @Test public void testLifecycle_S2_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val2 = mock(Object.class); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2, NOT_FAILED, null); Object val1 = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Highest-quality data source was first to produce result, other data sources got closed. */ @Test public void testLifecycle_I1_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val1a = mock(Object.class); setState(mSrc1, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val1a, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc3).close(); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val1a, NOT_FAILED, null); Object val1b = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Highest-quality data source was first to produce result, other data sources got closed. */ @Test public void testLifecycle_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val1b = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc3).close(); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val1b, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Early close with intermediate result. */ @Test public void testLifecycle_I2_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val2a = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); testClose(dataSource, mSrc1, mSrc2); verifySubscriber(dataSource, null, ON_CANCELLATION); verifyState(dataSource, null, CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Early close with no results. */ @Test public void testLifecycle_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); testClose(dataSource, mSrc1, mSrc2, mSrc3); verifySubscriber(dataSource, null, ON_CANCELLATION); verifyState(dataSource, null, CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Ignore callbacks after closed. */ @Test public void testLifecycle_I2_C_S1() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); Object val2a = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); testClose(dataSource, mSrc1, mSrc2); verifySubscriber(dataSource, null, ON_CANCELLATION); verifyState(dataSource, null, CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); Object val = mock(Object.class); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, null, CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Test data source without result */ @Test public void testLifecycle_WithoutResult_NI2_NS2_I3_S3_S1_C() { DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); DataSubscriber<Object> subscriber3 = verifyGetAndSubscribe(mDataSourceSupplier3, mSrc3); // I2 gets ignored because there is no result setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); // S2 gets ignored because there is no result setState(mSrc2, NOT_CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc2, NO_INTERACTIONS); verifyState(dataSource, null, NOT_CLOSED, NOT_FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); Object val3a = mock(Object.class); setState(mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3a, NOT_FAILED, null); subscriber3.onNewResult(mSrc3); verifySubscriber(dataSource, mSrc3, ON_NEW_RESULT); verifyState(dataSource, mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3a, NOT_FAILED, null); Object val3b = mock(Object.class); setState(mSrc3, NOT_CLOSED, FINISHED, WITH_RESULT, val3b, NOT_FAILED, null); subscriber3.onNewResult(mSrc3); verifySubscriber(dataSource, mSrc3, ON_NEW_RESULT); verifyState(dataSource, mSrc3, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val3b, NOT_FAILED, null); Object val = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc3).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Immediate result of low-res data source followed by delayed result of the first data source. */ @Test public void testLifecycle_ImmediateLowRes() { Object val2a = mock(Object.class); setState(mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); respondOnSubscribe(mSrc2, ON_NEW_RESULT); DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); DataSubscriber<Object> subscriber2 = verifyGetAndSubscribeM(mDataSourceSupplier2, mSrc2); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2a, NOT_FAILED, null); Object val2b = mock(Object.class); setState(mSrc2, NOT_CLOSED, FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); subscriber2.onNewResult(mSrc2); verifySubscriber(dataSource, mSrc2, ON_NEW_RESULT); verifyState(dataSource, mSrc2, NOT_CLOSED, NOT_FINISHED, WITH_RESULT, val2b, NOT_FAILED, null); Object val = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); subscriber1.onNewResult(mSrc1); mInOrder.verify(mSrc2).close(); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } /** * Immediate finish of the first data source. */ @Test public void testLifecycle_ImmediateFinish() { Object val = mock(Object.class); setState(mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); respondOnSubscribe(mSrc1, ON_NEW_RESULT); DataSource<Object> dataSource = getAndSubscribe(); DataSubscriber<Object> subscriber1 = verifyGetAndSubscribeM(mDataSourceSupplier1, mSrc1); verifySubscriber(dataSource, mSrc1, ON_NEW_RESULT); verifyState(dataSource, mSrc1, NOT_CLOSED, FINISHED, WITH_RESULT, val, NOT_FAILED, null); testClose(dataSource, mSrc1); verifyState(dataSource, null, CLOSED, FINISHED, WITHOUT_RESULT, null, NOT_FAILED, null); } }