diff options
Diffstat (limited to 'android/arch/persistence/room/integration/testapp/test/QueryTransactionTest.java')
-rw-r--r-- | android/arch/persistence/room/integration/testapp/test/QueryTransactionTest.java | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/android/arch/persistence/room/integration/testapp/test/QueryTransactionTest.java b/android/arch/persistence/room/integration/testapp/test/QueryTransactionTest.java deleted file mode 100644 index 854c8627..00000000 --- a/android/arch/persistence/room/integration/testapp/test/QueryTransactionTest.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.arch.persistence.room.integration.testapp.test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -import android.arch.core.executor.ArchTaskExecutor; -import android.arch.core.executor.testing.CountingTaskExecutorRule; -import android.arch.lifecycle.Lifecycle; -import android.arch.lifecycle.LiveData; -import android.arch.lifecycle.Observer; -import android.arch.paging.LivePagedListProvider; -import android.arch.paging.PagedList; -import android.arch.paging.TiledDataSource; -import android.arch.persistence.room.Dao; -import android.arch.persistence.room.Database; -import android.arch.persistence.room.Entity; -import android.arch.persistence.room.Ignore; -import android.arch.persistence.room.Insert; -import android.arch.persistence.room.PrimaryKey; -import android.arch.persistence.room.Query; -import android.arch.persistence.room.Relation; -import android.arch.persistence.room.Room; -import android.arch.persistence.room.RoomDatabase; -import android.arch.persistence.room.RoomWarnings; -import android.arch.persistence.room.Transaction; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.test.InstrumentationRegistry; -import android.support.test.filters.SmallTest; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; - -import io.reactivex.Flowable; -import io.reactivex.Maybe; -import io.reactivex.Single; -import io.reactivex.observers.TestObserver; -import io.reactivex.schedulers.Schedulers; -import io.reactivex.subscribers.TestSubscriber; - -@SmallTest -@RunWith(Parameterized.class) -public class QueryTransactionTest { - @Rule - public CountingTaskExecutorRule countingTaskExecutorRule = new CountingTaskExecutorRule(); - private static final AtomicInteger sStartedTransactionCount = new AtomicInteger(0); - private TransactionDb mDb; - private final boolean mUseTransactionDao; - private Entity1Dao mDao; - private final LiveDataQueryTest.TestLifecycleOwner mLifecycleOwner = new LiveDataQueryTest - .TestLifecycleOwner(); - - @NonNull - @Parameterized.Parameters(name = "useTransaction_{0}") - public static Boolean[] getParams() { - return new Boolean[]{false, true}; - } - - public QueryTransactionTest(boolean useTransactionDao) { - mUseTransactionDao = useTransactionDao; - } - - @Before - public void initDb() { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mLifecycleOwner.handleEvent(Lifecycle.Event.ON_START); - } - }); - - resetTransactionCount(); - mDb = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(), - TransactionDb.class).build(); - mDao = mUseTransactionDao ? mDb.transactionDao() : mDb.dao(); - drain(); - } - - @After - public void closeDb() { - InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { - @Override - public void run() { - mLifecycleOwner.handleEvent(Lifecycle.Event.ON_DESTROY); - } - }); - drain(); - mDb.close(); - } - - @Test - public void readList() { - mDao.insert(new Entity1(1, "foo")); - resetTransactionCount(); - - int expectedTransactionCount = mUseTransactionDao ? 1 : 0; - List<Entity1> allEntities = mDao.allEntities(); - assertTransactionCount(allEntities, expectedTransactionCount); - } - - @Test - public void liveData() { - LiveData<List<Entity1>> listLiveData = mDao.liveData(); - observeForever(listLiveData); - drain(); - assertThat(listLiveData.getValue(), is(Collections.<Entity1>emptyList())); - - resetTransactionCount(); - mDao.insert(new Entity1(1, "foo")); - drain(); - - //noinspection ConstantConditions - assertThat(listLiveData.getValue().size(), is(1)); - int expectedTransactionCount = mUseTransactionDao ? 2 : 1; - assertTransactionCount(listLiveData.getValue(), expectedTransactionCount); - } - - @Test - public void flowable() { - Flowable<List<Entity1>> flowable = mDao.flowable(); - TestSubscriber<List<Entity1>> subscriber = observe(flowable); - drain(); - assertThat(subscriber.values().size(), is(1)); - - resetTransactionCount(); - mDao.insert(new Entity1(1, "foo")); - drain(); - - List<Entity1> allEntities = subscriber.values().get(1); - assertThat(allEntities.size(), is(1)); - int expectedTransactionCount = mUseTransactionDao ? 2 : 1; - assertTransactionCount(allEntities, expectedTransactionCount); - } - - @Test - public void maybe() { - mDao.insert(new Entity1(1, "foo")); - resetTransactionCount(); - - int expectedTransactionCount = mUseTransactionDao ? 1 : 0; - Maybe<List<Entity1>> listMaybe = mDao.maybe(); - TestObserver<List<Entity1>> observer = observe(listMaybe); - drain(); - List<Entity1> allEntities = observer.values().get(0); - assertTransactionCount(allEntities, expectedTransactionCount); - } - - @Test - public void single() { - mDao.insert(new Entity1(1, "foo")); - resetTransactionCount(); - - int expectedTransactionCount = mUseTransactionDao ? 1 : 0; - Single<List<Entity1>> listMaybe = mDao.single(); - TestObserver<List<Entity1>> observer = observe(listMaybe); - drain(); - List<Entity1> allEntities = observer.values().get(0); - assertTransactionCount(allEntities, expectedTransactionCount); - } - - @Test - public void relation() { - mDao.insert(new Entity1(1, "foo")); - mDao.insert(new Child(1, 1)); - mDao.insert(new Child(2, 1)); - resetTransactionCount(); - - List<Entity1WithChildren> result = mDao.withRelation(); - int expectedTransactionCount = mUseTransactionDao ? 1 : 0; - assertTransactionCountWithChildren(result, expectedTransactionCount); - } - - @Test - public void pagedList() { - LiveData<PagedList<Entity1>> pagedList = mDao.pagedList().create(null, 10); - observeForever(pagedList); - drain(); - assertThat(sStartedTransactionCount.get(), is(mUseTransactionDao ? 0 : 0)); - - mDao.insert(new Entity1(1, "foo")); - drain(); - //noinspection ConstantConditions - assertThat(pagedList.getValue().size(), is(1)); - assertTransactionCount(pagedList.getValue(), mUseTransactionDao ? 2 : 1); - - mDao.insert(new Entity1(2, "bar")); - drain(); - assertThat(pagedList.getValue().size(), is(2)); - assertTransactionCount(pagedList.getValue(), mUseTransactionDao ? 4 : 2); - } - - @Test - public void dataSource() { - mDao.insert(new Entity1(2, "bar")); - drain(); - resetTransactionCount(); - TiledDataSource<Entity1> dataSource = mDao.dataSource(); - dataSource.loadRange(0, 10); - assertThat(sStartedTransactionCount.get(), is(mUseTransactionDao ? 1 : 0)); - } - - private void assertTransactionCount(List<Entity1> allEntities, int expectedTransactionCount) { - assertThat(sStartedTransactionCount.get(), is(expectedTransactionCount)); - assertThat(allEntities.isEmpty(), is(false)); - for (Entity1 entity1 : allEntities) { - assertThat(entity1.transactionId, is(expectedTransactionCount)); - } - } - - private void assertTransactionCountWithChildren(List<Entity1WithChildren> allEntities, - int expectedTransactionCount) { - assertThat(sStartedTransactionCount.get(), is(expectedTransactionCount)); - assertThat(allEntities.isEmpty(), is(false)); - for (Entity1WithChildren entity1 : allEntities) { - assertThat(entity1.transactionId, is(expectedTransactionCount)); - assertThat(entity1.children, notNullValue()); - assertThat(entity1.children.isEmpty(), is(false)); - for (Child child : entity1.children) { - assertThat(child.transactionId, is(expectedTransactionCount)); - } - } - } - - private void resetTransactionCount() { - sStartedTransactionCount.set(0); - } - - private void drain() { - try { - countingTaskExecutorRule.drainTasks(30, TimeUnit.SECONDS); - } catch (InterruptedException e) { - throw new AssertionError("interrupted", e); - } catch (TimeoutException e) { - throw new AssertionError("drain timed out", e); - } - } - - private <T> TestSubscriber<T> observe(final Flowable<T> flowable) { - TestSubscriber<T> subscriber = new TestSubscriber<>(); - flowable.observeOn(Schedulers.from(ArchTaskExecutor.getMainThreadExecutor())) - .subscribeWith(subscriber); - return subscriber; - } - - private <T> TestObserver<T> observe(final Maybe<T> maybe) { - TestObserver<T> observer = new TestObserver<>(); - maybe.observeOn(Schedulers.from(ArchTaskExecutor.getMainThreadExecutor())) - .subscribeWith(observer); - return observer; - } - - private <T> TestObserver<T> observe(final Single<T> single) { - TestObserver<T> observer = new TestObserver<>(); - single.observeOn(Schedulers.from(ArchTaskExecutor.getMainThreadExecutor())) - .subscribeWith(observer); - return observer; - } - - private <T> void observeForever(final LiveData<T> liveData) { - FutureTask<Void> futureTask = new FutureTask<>(new Callable<Void>() { - @Override - public Void call() throws Exception { - liveData.observe(mLifecycleOwner, new Observer<T>() { - @Override - public void onChanged(@Nullable T t) { - - } - }); - return null; - } - }); - ArchTaskExecutor.getMainThreadExecutor().execute(futureTask); - try { - futureTask.get(); - } catch (InterruptedException e) { - throw new AssertionError("interrupted", e); - } catch (ExecutionException e) { - throw new AssertionError("execution error", e); - } - } - - @SuppressWarnings("WeakerAccess") - static class Entity1WithChildren extends Entity1 { - @Relation(entity = Child.class, parentColumn = "id", - entityColumn = "entity1Id") - public List<Child> children; - - Entity1WithChildren(int id, String value) { - super(id, value); - } - } - - @SuppressWarnings("WeakerAccess") - @Entity - static class Child { - @PrimaryKey(autoGenerate = true) - public int id; - public int entity1Id; - @Ignore - public final int transactionId = sStartedTransactionCount.get(); - - Child(int id, int entity1Id) { - this.id = id; - this.entity1Id = entity1Id; - } - } - - @SuppressWarnings("WeakerAccess") - @Entity - static class Entity1 { - @PrimaryKey(autoGenerate = true) - public int id; - public String value; - @Ignore - public final int transactionId = sStartedTransactionCount.get(); - - Entity1(int id, String value) { - this.id = id; - this.value = value; - } - } - - // we don't support dao inheritance for queries so for now, go with this - interface Entity1Dao { - String SELECT_ALL = "select * from Entity1"; - - List<Entity1> allEntities(); - - Flowable<List<Entity1>> flowable(); - - Maybe<List<Entity1>> maybe(); - - Single<List<Entity1>> single(); - - LiveData<List<Entity1>> liveData(); - - List<Entity1WithChildren> withRelation(); - - LivePagedListProvider<Integer, Entity1> pagedList(); - - TiledDataSource<Entity1> dataSource(); - - @Insert - void insert(Entity1 entity1); - - @Insert - void insert(Child entity1); - } - - @Dao - interface EntityDao extends Entity1Dao { - @Override - @Query(SELECT_ALL) - List<Entity1> allEntities(); - - @Override - @Query(SELECT_ALL) - Flowable<List<Entity1>> flowable(); - - @Override - @Query(SELECT_ALL) - LiveData<List<Entity1>> liveData(); - - @Override - @Query(SELECT_ALL) - Maybe<List<Entity1>> maybe(); - - @Override - @Query(SELECT_ALL) - Single<List<Entity1>> single(); - - @Override - @Query(SELECT_ALL) - @SuppressWarnings(RoomWarnings.RELATION_QUERY_WITHOUT_TRANSACTION) - List<Entity1WithChildren> withRelation(); - - @Override - @Query(SELECT_ALL) - LivePagedListProvider<Integer, Entity1> pagedList(); - - @Override - @Query(SELECT_ALL) - TiledDataSource<Entity1> dataSource(); - } - - @Dao - interface TransactionDao extends Entity1Dao { - @Override - @Transaction - @Query(SELECT_ALL) - List<Entity1> allEntities(); - - @Override - @Transaction - @Query(SELECT_ALL) - Flowable<List<Entity1>> flowable(); - - @Override - @Transaction - @Query(SELECT_ALL) - LiveData<List<Entity1>> liveData(); - - @Override - @Transaction - @Query(SELECT_ALL) - Maybe<List<Entity1>> maybe(); - - @Override - @Transaction - @Query(SELECT_ALL) - Single<List<Entity1>> single(); - - @Override - @Transaction - @Query(SELECT_ALL) - List<Entity1WithChildren> withRelation(); - - @Override - @Transaction - @Query(SELECT_ALL) - LivePagedListProvider<Integer, Entity1> pagedList(); - - @Override - @Transaction - @Query(SELECT_ALL) - TiledDataSource<Entity1> dataSource(); - } - - @Database(version = 1, entities = {Entity1.class, Child.class}, exportSchema = false) - abstract static class TransactionDb extends RoomDatabase { - abstract EntityDao dao(); - - abstract TransactionDao transactionDao(); - - @Override - public void beginTransaction() { - super.beginTransaction(); - sStartedTransactionCount.incrementAndGet(); - } - } -} |