Skip to content
Browse files

Merge pull request #629 from geralt-encore/rx-completable

rx.Completable support for write operations
  • Loading branch information...
2 parents bbb3bae + deaed1f commit 52c18835c611270bc38aa55461731f2205d44b77 @artem-zinnatullin artem-zinnatullin committed
Showing with 1,100 additions and 5 deletions.
  1. +1 −1 build.gradle
  2. +18 −0 storio-common/src/main/java/com/pushtorefresh/storio/operations/PreparedWriteOperation.java
  3. +46 −0 ...in/java/com/pushtorefresh/storio/operations/internal/OnSubscribeExecuteAsBlockingCompletable.java
  4. +68 −0 ...ava/com/pushtorefresh/storio/operations/internal/OnSubscribeExecuteAsBlockingCompletableTest.java
  5. +2 −2 storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDelete.java
  6. +21 −0 ...sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteByQuery.java
  7. +21 −0 ...ain/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteCollectionOfObjects.java
  8. +21 −0 ...-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteObject.java
  9. +2 −2 storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPut.java
  10. +21 −0 .../src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutCollectionOfObjects.java
  11. +21 −0 ...sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValues.java
  12. +21 −0 ...rc/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesIterable.java
  13. +21 −0 storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutObject.java
  14. +38 −0 storio-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/design/DeleteOperationDesignTest.java
  15. +36 −0 storio-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/design/PutOperationDesignTest.java
  16. +9 −0 storio-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/delete/DeleteStub.java
  17. +74 −0 ...te/src/test/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteByQueryTest.java
  18. +172 −0 ...java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteCollectionOfObjectsTest.java
  19. +58 −0 ...ite/src/test/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteObjectTest.java
  20. +219 −0 .../test/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutCollectionOfObjectsTest.java
  21. +114 −0 ...est/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesIterableTest.java
  22. +15 −0 ...te/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesTest.java
  23. +62 −0 ...io-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutObjectTest.java
  24. +10 −0 storio-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PutContentValuesStub.java
  25. +9 −0 storio-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PutObjectsStub.java
View
2 build.gradle
@@ -53,7 +53,7 @@ def daggerVersion = '2.0.1'
ext.libraries = [
// Core libraries
supportAnnotations : 'com.android.support:support-annotations:' + supportLibsVersion,
- rxJava : 'io.reactivex:rxjava:1.1.0',
+ rxJava : 'io.reactivex:rxjava:1.1.1',
// Parts of StorIO
storIOCommon : project(':storio-common'),
View
18 storio-common/src/main/java/com/pushtorefresh/storio/operations/PreparedWriteOperation.java
@@ -0,0 +1,18 @@
+package com.pushtorefresh.storio.operations;
+
+import android.support.annotation.CheckResult;
+import android.support.annotation.NonNull;
+
+import rx.Completable;
+
+/**
+ * Common API of prepared write operations
+ *
+ * @param <Result> type of result
+ */
+public interface PreparedWriteOperation<Result> extends PreparedOperation<Result> {
+
+ @NonNull
+ @CheckResult
+ Completable asRxComletable();
+}
View
46 ...com/pushtorefresh/storio/operations/internal/OnSubscribeExecuteAsBlockingCompletable.java
@@ -0,0 +1,46 @@
+package com.pushtorefresh.storio.operations.internal;
+
+import android.support.annotation.NonNull;
+
+import com.pushtorefresh.storio.StorIOException;
+import com.pushtorefresh.storio.operations.PreparedOperation;
+
+import rx.Completable;
+
+/**
+ * Required to avoid problems with ClassLoader when RxJava is not in ClassPath
+ * We can not use anonymous classes from RxJava directly in StorIO, ClassLoader won't be happy :(
+ * <p>
+ * For internal usage only!
+ */
+public final class OnSubscribeExecuteAsBlockingCompletable implements Completable.CompletableOnSubscribe {
+
+ @NonNull
+ private final PreparedOperation preparedOperation;
+
+ private OnSubscribeExecuteAsBlockingCompletable(@NonNull PreparedOperation preparedOperation) {
+ this.preparedOperation = preparedOperation;
+ }
+
+ /**
+ * Creates new instance of {@link OnSubscribeExecuteAsBlockingCompletable}
+ *
+ * @param preparedOperation non-null instance of {@link PreparedOperation} which will be used to provide result to subscribers
+ * @return new instance of {@link OnSubscribeExecuteAsBlockingCompletable}
+ */
+ @NonNull
+ public static Completable.CompletableOnSubscribe newInstance(@NonNull PreparedOperation preparedOperation) {
+ return new OnSubscribeExecuteAsBlockingCompletable(preparedOperation);
+ }
+
+ @Override
+ public void call(@NonNull Completable.CompletableSubscriber subscriber) {
+ try {
+ preparedOperation.executeAsBlocking();
+
+ subscriber.onCompleted();
+ } catch (StorIOException e) {
+ subscriber.onError(e);
+ }
+ }
+}
View
68 ...pushtorefresh/storio/operations/internal/OnSubscribeExecuteAsBlockingCompletableTest.java
@@ -0,0 +1,68 @@
+package com.pushtorefresh.storio.operations.internal;
+
+import com.pushtorefresh.storio.StorIOException;
+import com.pushtorefresh.storio.operations.PreparedWriteOperation;
+
+import org.junit.Test;
+
+import rx.Completable;
+import rx.observers.TestSubscriber;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class OnSubscribeExecuteAsBlockingCompletableTest {
+
+ @SuppressWarnings("ResourceType")
+ @Test
+ public void shouldExecuteAsBlockingAfterSubscription() {
+ final PreparedWriteOperation preparedOperation = mock(PreparedWriteOperation.class);
+
+ TestSubscriber testSubscriber = new TestSubscriber();
+
+ verifyZeroInteractions(preparedOperation);
+
+ Completable completable = Completable.create(OnSubscribeExecuteAsBlockingCompletable.newInstance(preparedOperation));
+
+ verifyZeroInteractions(preparedOperation);
+
+ completable.subscribe(testSubscriber);
+
+ testSubscriber.assertNoErrors();
+ testSubscriber.assertCompleted();
+
+ verify(preparedOperation).executeAsBlocking();
+ verify(preparedOperation, times(0)).asRxObservable();
+ verify(preparedOperation, times(0)).asRxSingle();
+ verify(preparedOperation, times(0)).asRxComletable();
+ }
+
+ @SuppressWarnings({"ThrowableInstanceNeverThrown", "ResourceType"})
+ @Test
+ public void shouldCallOnErrorIfExceptionOccured() {
+ final PreparedWriteOperation preparedOperation = mock(PreparedWriteOperation.class);
+
+ StorIOException expectedException = new StorIOException("test exception");
+
+ when(preparedOperation.executeAsBlocking()).thenThrow(expectedException);
+
+ TestSubscriber testSubscriber = new TestSubscriber();
+
+ Completable completable = Completable.create(OnSubscribeExecuteAsBlockingCompletable.newInstance(preparedOperation));
+
+ verifyZeroInteractions(preparedOperation);
+
+ completable.subscribe(testSubscriber);
+
+ testSubscriber.assertError(expectedException);
+ testSubscriber.assertTerminalEvent();
+
+ verify(preparedOperation).executeAsBlocking();
+ verify(preparedOperation, times(0)).asRxObservable();
+ verify(preparedOperation, times(0)).asRxSingle();
+ verify(preparedOperation, times(0)).asRxComletable();
+ }
+}
View
4 ...qlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDelete.java
@@ -2,7 +2,7 @@
import android.support.annotation.NonNull;
-import com.pushtorefresh.storio.operations.PreparedOperation;
+import com.pushtorefresh.storio.operations.PreparedWriteOperation;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery;
@@ -13,7 +13,7 @@
*
* @param <T> type of object to delete.
*/
-public abstract class PreparedDelete<T> implements PreparedOperation<T> {
+public abstract class PreparedDelete<T> implements PreparedWriteOperation<T> {
@NonNull
protected final StorIOSQLite storIOSQLite;
View
21 ...rc/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteByQuery.java
@@ -7,11 +7,13 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -126,6 +128,25 @@ public DeleteResult executeAsBlocking() {
}
/**
+ * Creates {@link Completable} which will perform Delete Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Delete Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedDeleteByQuery}.
*/
public static class Builder {
View
21 .../com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteCollectionOfObjects.java
@@ -7,6 +7,7 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
@@ -21,6 +22,7 @@
import java.util.Map;
import java.util.Set;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -231,6 +233,25 @@
}
/**
+ * Creates {@link Completable} which will perform Delete Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Delete Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedDeleteCollectionOfObjects}.
*
* @param <T> type of objects to delete.
View
21 ...src/main/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteObject.java
@@ -7,11 +7,13 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -152,6 +154,25 @@ public DeleteResult executeAsBlocking() {
}
/**
+ * Creates {@link Completable} which will perform Delete Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Delete Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedDeleteObject}.
*
* @param <T> type of object to delete.
View
4 storio-sqlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPut.java
@@ -3,7 +3,7 @@
import android.content.ContentValues;
import android.support.annotation.NonNull;
-import com.pushtorefresh.storio.operations.PreparedOperation;
+import com.pushtorefresh.storio.operations.PreparedWriteOperation;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import java.util.Arrays;
@@ -13,7 +13,7 @@
* Prepared Put Operation for {@link StorIOSQLite} which performs insert or update data
* in {@link StorIOSQLite}.
*/
-public abstract class PreparedPut<Result> implements PreparedOperation<Result> {
+public abstract class PreparedPut<Result> implements PreparedWriteOperation<Result> {
@NonNull
protected final StorIOSQLite storIOSQLite;
View
21 ...n/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutCollectionOfObjects.java
@@ -7,6 +7,7 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
@@ -21,6 +22,7 @@
import java.util.Map;
import java.util.Set;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -223,6 +225,25 @@
}
/**
+ * Creates {@link Completable} which will perform Put Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Put Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedPutCollectionOfObjects}
*
* @param <T> type of objects to put
View
21 ...rc/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValues.java
@@ -7,10 +7,12 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -127,6 +129,25 @@ public PutResult executeAsBlocking() {
}
/**
+ * Creates {@link Completable} which will perform Put Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Put Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedPutContentValues}.
*/
public static class Builder {
View
21 ...java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesIterable.java
@@ -7,6 +7,7 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
@@ -16,6 +17,7 @@
import java.util.Map;
import java.util.Set;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -181,6 +183,25 @@
}
/**
+ * Creates {@link Completable} which will perform Put Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Put Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedPutContentValuesIterable}
*/
public static class Builder {
View
21 ...qlite/src/main/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutObject.java
@@ -7,11 +7,13 @@
import com.pushtorefresh.storio.StorIOException;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlocking;
+import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingCompletable;
import com.pushtorefresh.storio.operations.internal.OnSubscribeExecuteAsBlockingSingle;
import com.pushtorefresh.storio.sqlite.Changes;
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.schedulers.Schedulers;
@@ -152,6 +154,25 @@ public PutResult executeAsBlocking() {
}
/**
+ * Creates {@link Completable} which will perform Put Operation lazily when somebody subscribes to it.
+ * <dl>
+ * <dt><b>Scheduler:</b></dt>
+ * <dd>Operates on {@link Schedulers#io()}.</dd>
+ * </dl>
+ *
+ * @return non-null {@link Completable} which will perform Put Operation.
+ */
+ @NonNull
+ @CheckResult
+ @Override
+ public Completable asRxComletable() {
+ throwExceptionIfRxJavaIsNotAvailable("asRxCompetable()");
+ return Completable
+ .create(OnSubscribeExecuteAsBlockingCompletable.newInstance(this))
+ .subscribeOn(Schedulers.io());
+ }
+
+ /**
* Builder for {@link PreparedPutObject}.
*
* @param <T> type of object to put.
View
38 ...qlite/src/test/java/com/pushtorefresh/storio/sqlite/design/DeleteOperationDesignTest.java
@@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
@@ -124,4 +125,41 @@ public void deleteByQuerySingle() {
.prepare()
.asRxSingle();
}
+
+ @Test
+ public void deleteObjectCompletable() {
+ User user = newUser();
+
+ Completable completableDelete = storIOSQLite()
+ .delete()
+ .object(user)
+ .withDeleteResolver(UserTableMeta.DELETE_RESOLVER)
+ .prepare()
+ .asRxComletable();
+ }
+
+ @Test
+ public void deleteCollectionOfObjectsCompletable() {
+ List<User> users = new ArrayList<User>();
+
+ Completable completableDelete = storIOSQLite()
+ .delete()
+ .objects(users)
+ .withDeleteResolver(UserTableMeta.DELETE_RESOLVER)
+ .prepare()
+ .asRxComletable();
+ }
+
+ @Test
+ public void deleteByQueryCompletable() {
+ Completable completableDelete = storIOSQLite()
+ .delete()
+ .byQuery(DeleteQuery.builder()
+ .table("users")
+ .where("email = ?")
+ .whereArgs("artem.zinnatullin@gmail.com")
+ .build())
+ .prepare()
+ .asRxComletable();
+ }
}
View
36 ...o-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/design/PutOperationDesignTest.java
@@ -14,6 +14,7 @@
import java.util.Arrays;
+import rx.Completable;
import rx.Observable;
import rx.Single;
@@ -174,4 +175,39 @@ public void putContentValuesIterableSingle() {
.asRxSingle();
}
+ @Test
+ public void putObjectCompletable() {
+ User user = newUser();
+
+ Completable completablePut = storIOSQLite()
+ .put()
+ .object(user)
+ .withPutResolver(UserTableMeta.PUT_RESOLVER)
+ .prepare()
+ .asRxComletable();
+ }
+
+ @Test
+ public void putContentValuesCompletable() {
+ Completable completablePut = storIOSQLite()
+ .put()
+ .contentValues(mock(ContentValues.class))
+ .withPutResolver(CONTENT_VALUES_PUT_RESOLVER)
+ .prepare()
+ .asRxComletable();
+ }
+
+ @Test
+ public void putContentValuesIterableCompletable() {
+ Iterable<ContentValues> contentValuesIterable
+ = Arrays.asList(mock(ContentValues.class));
+
+ Completable completablePut = storIOSQLite()
+ .put()
+ .contentValues(contentValuesIterable)
+ .withPutResolver(CONTENT_VALUES_PUT_RESOLVER)
+ .prepare()
+ .asRxComletable();
+ }
+
}
View
9 ...io-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/delete/DeleteStub.java
@@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.functions.Action1;
@@ -200,6 +201,10 @@ public void call(DeleteResults<TestItem> deleteResults) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForMultipleObjects(@NonNull Completable completable) {
+ verifyBehaviorForMultipleObjects(completable.<DeleteResults<TestItem>>toObservable());
+ }
+
void verifyBehaviorForOneObject(@NonNull DeleteResult deleteResult) {
verifyBehaviorForMultipleObjects(DeleteResults.newInstance(singletonMap(itemsRequestedForDelete.get(0), deleteResult)));
}
@@ -217,6 +222,10 @@ public void call(DeleteResult deleteResult) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForOneObject(@NonNull Completable completable) {
+ verifyBehaviorForOneObject(completable.<DeleteResult>toObservable());
+ }
+
void verifyBehaviorForOneObject(@NonNull Single<DeleteResult> single) {
new ObservableBehaviorChecker<DeleteResult>()
.observable(single.toObservable())
View
74 ...est/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteByQueryTest.java
@@ -135,6 +135,45 @@ public void shouldPerformDeletionByQuerySingle() {
}
@Test
+ public void shouldPerformDeletionByQueryCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ final DeleteQuery deleteQuery = DeleteQuery.builder()
+ .table("test_table")
+ .where("column1 = ?")
+ .whereArgs(1)
+ .build();
+
+ //noinspection unchecked
+ final DeleteResolver<DeleteQuery> deleteResolver = mock(DeleteResolver.class);
+
+ final DeleteResult expectedDeleteResult = DeleteResult.newInstance(1, deleteQuery.table());
+
+ when(deleteResolver.performDelete(same(storIOSQLite), same(deleteQuery)))
+ .thenReturn(expectedDeleteResult);
+
+ final TestSubscriber<DeleteResult> testSubscriber = new TestSubscriber<DeleteResult>();
+
+ new PreparedDeleteByQuery.Builder(storIOSQLite, deleteQuery)
+ .withDeleteResolver(deleteResolver)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoErrors();
+ testSubscriber.assertNoValues();
+
+ verify(storIOSQLite).lowLevel();
+ verify(deleteResolver).performDelete(same(storIOSQLite), same(deleteQuery));
+ verify(internal).notifyAboutChanges(eq(Changes.newInstance(deleteQuery.table())));
+ verifyNoMoreInteractions(storIOSQLite, internal, deleteResolver);
+ }
+
+ @Test
public void shouldWrapExceptionIntoStorIOExceptionBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -234,6 +273,41 @@ public void shouldWrapExceptionIntoStorIOExceptionSingle() {
}
@Test
+ public void shouldWrapExceptionIntoStorIOExceptionCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ //noinspection unchecked
+ final DeleteResolver<DeleteQuery> deleteResolver = mock(DeleteResolver.class);
+
+ when(deleteResolver.performDelete(same(storIOSQLite), any(DeleteQuery.class)))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final TestSubscriber<DeleteResult> testSubscriber = new TestSubscriber<DeleteResult>();
+
+ new PreparedDeleteByQuery.Builder(storIOSQLite, DeleteQuery.builder().table("test_table").build())
+ .withDeleteResolver(deleteResolver)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ verify(deleteResolver).performDelete(same(storIOSQLite), any(DeleteQuery.class));
+ verifyNoMoreInteractions(storIOSQLite, internal, deleteResolver);
+ }
+
+ @Test
public void shouldNotNotifyIfWasNotDeleted() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
View
172 .../pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteCollectionOfObjectsTest.java
@@ -10,6 +10,7 @@
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;
@@ -159,6 +160,38 @@ public void shouldDeleteObjectsWithoutTypeMappingWithTransactionAsSingle() {
deleteStub.verifyBehaviorForMultipleObjects(single);
}
+
+ @Test
+ public void shouldDeleteObjectsWithoutTypeMappingWithoutTransactionAsCompletable() {
+ final DeleteStub deleteStub
+ = DeleteStub.newStubForMultipleObjectsWithoutTypeMappingWithoutTransaction();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .objects(deleteStub.itemsRequestedForDelete)
+ .useTransaction(false)
+ .withDeleteResolver(deleteStub.deleteResolver)
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForMultipleObjects(completable);
+ }
+
+ @Test
+ public void shouldDeleteObjectsWithoutTypeMappingWithTransactionAsCompletable() {
+ final DeleteStub deleteStub
+ = DeleteStub.newStubForMultipleObjectsWithoutTypeMappingWithTransaction();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .objects(deleteStub.itemsRequestedForDelete)
+ .useTransaction(true)
+ .withDeleteResolver(deleteStub.deleteResolver)
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForMultipleObjects(completable);
+ }
}
public static class WithTypeMapping {
@@ -282,6 +315,36 @@ public void shouldDeleteObjectsWithTypeMappingWithTransactionSingle() {
deleteStub.verifyBehaviorForMultipleObjects(single);
}
+
+ @Test
+ public void shouldDeleteObjectsWithTypeMappingWithoutTransactionCompletable() {
+ final DeleteStub deleteStub
+ = DeleteStub.newStubForMultipleObjectsWithTypeMappingWithoutTransaction();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .objects(deleteStub.itemsRequestedForDelete)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForMultipleObjects(completable);
+ }
+
+ @Test
+ public void shouldDeleteObjectsWithTypeMappingWithTransactionCompletable() {
+ final DeleteStub deleteStub
+ = DeleteStub.newStubForMultipleObjectsWithTypeMappingWithTransaction();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .objects(deleteStub.itemsRequestedForDelete)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForMultipleObjects(completable);
+ }
}
public static class NoTypeMappingError {
@@ -387,6 +450,40 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutTransactionWithout
}
@Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutTransactionWithoutAffectingDbAsCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ when(storIOSQLite.delete()).thenReturn(new PreparedDelete.Builder(storIOSQLite));
+
+ final List<TestItem> items = asList(TestItem.newInstance(), TestItem.newInstance());
+
+ final TestSubscriber<DeleteResults<TestItem>> testSubscriber = new TestSubscriber<DeleteResults<TestItem>>();
+
+ storIOSQLite
+ .delete()
+ .objects(items)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ assertThat(testSubscriber.getOnErrorEvents().get(0))
+ .isInstanceOf(StorIOException.class)
+ .hasCauseInstanceOf(IllegalStateException.class);
+
+ verify(storIOSQLite).delete();
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(TestItem.class);
+ verify(internal, never()).delete(any(DeleteQuery.class));
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
+
+ @Test
public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAffectingDbBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -485,6 +582,40 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAff
verify(internal, never()).delete(any(DeleteQuery.class));
verifyNoMoreInteractions(storIOSQLite, internal);
}
+
+ @Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAffectingDbAsCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ when(storIOSQLite.delete()).thenReturn(new PreparedDelete.Builder(storIOSQLite));
+
+ final List<TestItem> items = asList(TestItem.newInstance(), TestItem.newInstance());
+
+ final TestSubscriber<DeleteResults<TestItem>> testSubscriber = new TestSubscriber<DeleteResults<TestItem>>();
+
+ storIOSQLite
+ .delete()
+ .objects(items)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ assertThat(testSubscriber.getOnErrorEvents().get(0))
+ .isInstanceOf(StorIOException.class)
+ .hasCauseInstanceOf(IllegalStateException.class);
+
+ verify(storIOSQLite).delete();
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(TestItem.class);
+ verify(internal, never()).delete(any(DeleteQuery.class));
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
}
public static class OtherTests {
@@ -605,5 +736,46 @@ public void shouldFinishTransactionIfExceptionHasOccurredSingle() {
verify(deleteResolver).performDelete(same(storIOSQLite), anyObject());
verifyNoMoreInteractions(storIOSQLite, internal, deleteResolver);
}
+
+ @Test
+ public void shouldFinishTransactionIfExceptionHasOccurredCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ //noinspection unchecked
+ final DeleteResolver<Object> deleteResolver = mock(DeleteResolver.class);
+
+ when(deleteResolver.performDelete(same(storIOSQLite), anyObject()))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final TestSubscriber<DeleteResults<Object>> testSubscriber = new TestSubscriber<DeleteResults<Object>>();
+
+ new PreparedDeleteCollectionOfObjects.Builder<Object>(storIOSQLite, singletonList(new Object()))
+ .useTransaction(true)
+ .withDeleteResolver(deleteResolver)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ verify(internal).beginTransaction();
+ verify(internal, never()).setTransactionSuccessful();
+ verify(internal).endTransaction();
+
+ verify(storIOSQLite).lowLevel();
+ verify(deleteResolver).performDelete(same(storIOSQLite), anyObject());
+ verifyNoMoreInteractions(storIOSQLite, internal, deleteResolver);
+ }
}
}
View
58 ...test/java/com/pushtorefresh/storio/sqlite/operations/delete/PreparedDeleteObjectTest.java
@@ -8,6 +8,7 @@
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;
@@ -69,6 +70,20 @@ public void shouldDeleteObjectWithoutTypeMappingAsSingle() {
}
@Test
+ public void shouldDeleteObjectWithoutTypeMappingAsCompletable() {
+ final DeleteStub deleteStub = DeleteStub.newStubForOneObjectWithoutTypeMapping();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .object(deleteStub.itemsRequestedForDelete.get(0))
+ .withDeleteResolver(deleteStub.deleteResolver)
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForOneObject(completable);
+ }
+
+ @Test
public void shouldNotNotifyIfWasNotDeleted() {
final DeleteStub deleteStub = DeleteStub.newStubForOneObjectWithoutTypeMappingNothingDeleted();
@@ -123,6 +138,19 @@ public void shouldDeleteObjectWithTypeMappingAsSingle() {
deleteStub.verifyBehaviorForOneObject(single);
}
+
+ @Test
+ public void shouldDeleteObjectWithTypeMappingAsCompletable() {
+ final DeleteStub deleteStub = DeleteStub.newStubForOneObjectWithTypeMapping();
+
+ final Completable completable = deleteStub.storIOSQLite
+ .delete()
+ .object(deleteStub.itemsRequestedForDelete.get(0))
+ .prepare()
+ .asRxComletable();
+
+ deleteStub.verifyBehaviorForOneObject(completable);
+ }
}
public static class NoTypeMappingError {
@@ -215,5 +243,35 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutAffectingDbAsSingl
verify(internal, never()).delete(any(DeleteQuery.class));
verifyNoMoreInteractions(storIOSQLite, internal);
}
+
+ @Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutAffectingDbAsCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ when(storIOSQLite.delete()).thenReturn(new PreparedDelete.Builder(storIOSQLite));
+
+ final TestSubscriber<DeleteResult> testSubscriber = new TestSubscriber<DeleteResult>();
+
+ storIOSQLite
+ .delete()
+ .object(TestItem.newInstance())
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ assertThat(testSubscriber.getOnErrorEvents().get(0)).
+ hasCauseInstanceOf(IllegalStateException.class);
+
+ verify(storIOSQLite).delete();
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(TestItem.class);
+ verify(internal, never()).delete(any(DeleteQuery.class));
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
}
}
View
219 ...va/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutCollectionOfObjectsTest.java
@@ -13,6 +13,7 @@
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;
@@ -130,6 +131,38 @@ public void shouldPutObjectsWithoutTypeMappingWithTransactionAsSingle() {
putStub.verifyBehaviorForMultipleObjects(single);
}
+
+ @Test
+ public void shouldPutObjectsWithoutTypeMappingWithoutTransactionAsCompletable() {
+ final PutObjectsStub putStub
+ = PutObjectsStub.newPutStubForMultipleObjectsWithoutTypeMappingWithoutTransaction();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .objects(putStub.items)
+ .useTransaction(false)
+ .withPutResolver(putStub.putResolver)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleObjects(completable);
+ }
+
+ @Test
+ public void shouldPutObjectsWithoutTypeMappingWithTransactionAsCompletable() {
+ final PutObjectsStub putStub
+ = PutObjectsStub.newPutStubForMultipleObjectsWithoutTypeMappingWithTransaction();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .objects(putStub.items)
+ .useTransaction(true)
+ .withPutResolver(putStub.putResolver)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleObjects(completable);
+ }
}
public static class WithTypeMapping {
@@ -223,6 +256,36 @@ public void shouldPutObjectsWithTypeMappingWithTransactionAsSingle() {
putStub.verifyBehaviorForMultipleObjects(single);
}
+
+ @Test
+ public void shouldPutObjectsWithTypeMappingWithoutTransactionAsCompletable() {
+ final PutObjectsStub putStub
+ = PutObjectsStub.newPutStubForMultipleObjectsWithTypeMappingWithoutTransaction();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .objects(putStub.items)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleObjects(completable);
+ }
+
+ @Test
+ public void shouldPutObjectsWithTypeMappingWithTransactionAsCompletable() {
+ final PutObjectsStub putStub
+ = PutObjectsStub.newPutStubForMultipleObjectsWithTypeMappingWithTransaction();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .objects(putStub.items)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleObjects(completable);
+ }
}
public static class NoTypeMappingError {
@@ -331,6 +394,41 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutTransactionWithout
}
@Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutTransactionWithoutAffectingDbAsCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ when(storIOSQLite.put()).thenReturn(new PreparedPut.Builder(storIOSQLite));
+
+ final List<TestItem> items = asList(TestItem.newInstance(), TestItem.newInstance());
+
+ final TestSubscriber<PutResults<TestItem>> testSubscriber = new TestSubscriber<PutResults<TestItem>>();
+
+ storIOSQLite
+ .put()
+ .objects(items)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ assertThat(testSubscriber.getOnErrorEvents().get(0))
+ .isInstanceOf(StorIOException.class)
+ .hasCauseInstanceOf(IllegalStateException.class);
+
+ verify(storIOSQLite).put();
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(TestItem.class);
+ verify(internal, never()).insert(any(InsertQuery.class), any(ContentValues.class));
+ verify(internal, never()).update(any(UpdateQuery.class), any(ContentValues.class));
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
+
+ @Test
public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAffectingDbBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -432,6 +530,41 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAff
verify(internal, never()).update(any(UpdateQuery.class), any(ContentValues.class));
verifyNoMoreInteractions(storIOSQLite, internal);
}
+
+ @Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithTransactionWithoutAffectingDbAsCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ when(storIOSQLite.put()).thenReturn(new PreparedPut.Builder(storIOSQLite));
+
+ final List<TestItem> items = asList(TestItem.newInstance(), TestItem.newInstance());
+
+ final TestSubscriber<PutResults<TestItem>> testSubscriber = new TestSubscriber<PutResults<TestItem>>();
+
+ storIOSQLite
+ .put()
+ .objects(items)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ assertThat(testSubscriber.getOnErrorEvents().get(0))
+ .isInstanceOf(StorIOException.class)
+ .hasCauseInstanceOf(IllegalStateException.class);
+
+ verify(storIOSQLite).put();
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(TestItem.class);
+ verify(internal, never()).insert(any(InsertQuery.class), any(ContentValues.class));
+ verify(internal, never()).update(any(UpdateQuery.class), any(ContentValues.class));
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
}
public static class OtherTests {
@@ -558,6 +691,48 @@ public void shouldFinishTransactionIfExceptionHasOccurredSingle() {
}
@Test
+ public void shouldFinishTransactionIfExceptionHasOccurredCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ //noinspection unchecked
+ final PutResolver<Object> putResolver = mock(PutResolver.class);
+
+ when(putResolver.performPut(same(storIOSQLite), anyObject()))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final List<Object> objects = singletonList(new Object());
+
+ final TestSubscriber<PutResults<Object>> testSubscriber = new TestSubscriber<PutResults<Object>>();
+
+ new PreparedPutCollectionOfObjects.Builder<Object>(storIOSQLite, objects)
+ .useTransaction(true)
+ .withPutResolver(putResolver)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ verify(internal).beginTransaction();
+ verify(internal, never()).setTransactionSuccessful();
+ verify(internal).endTransaction();
+
+ verify(storIOSQLite).lowLevel();
+ verify(putResolver).performPut(same(storIOSQLite), anyObject());
+ verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
+ }
+
+ @Test
public void verifyBehaviorInCaseOfExceptionWithoutTransactionBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -682,5 +857,49 @@ public void verifyBehaviorInCaseOfExceptionWithoutTransactionSingle() {
verify(putResolver).performPut(same(storIOSQLite), anyObject());
verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
}
+
+ @Test
+ public void verifyBehaviorInCaseOfExceptionWithoutTransactionCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ //noinspection unchecked
+ final PutResolver<Object> putResolver = mock(PutResolver.class);
+
+ when(putResolver.performPut(same(storIOSQLite), anyObject()))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final List<Object> objects = singletonList(new Object());
+
+ final TestSubscriber<PutResults<Object>> testSubscriber = new TestSubscriber<PutResults<Object>>();
+
+ new PreparedPutCollectionOfObjects.Builder<Object>(storIOSQLite, objects)
+ .useTransaction(false)
+ .withPutResolver(putResolver)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ // Main checks of this test
+ verify(internal, never()).beginTransaction();
+ verify(internal, never()).setTransactionSuccessful();
+ verify(internal, never()).endTransaction();
+
+ verify(storIOSQLite).lowLevel();
+ verify(putResolver).performPut(same(storIOSQLite), anyObject());
+ verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
+ }
}
}
View
114 .../com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesIterableTest.java
@@ -9,6 +9,7 @@
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;
@@ -72,6 +73,21 @@ public void putMultipleSingleWithTransaction() {
}
@Test
+ public void putMultipleCompletableWithTransaction() {
+ final PutContentValuesStub putStub = PutContentValuesStub.newPutStubForMultipleContentValues(true);
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .contentValues(putStub.contentValues)
+ .withPutResolver(putStub.putResolver)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleContentValues(completable);
+ }
+
+ @Test
public void putMultipleBlockingWithoutTransaction() {
final PutContentValuesStub putStub = PutContentValuesStub.newPutStubForMultipleContentValues(false);
@@ -117,6 +133,21 @@ public void putMultipleSingleWithoutTransaction() {
}
@Test
+ public void putMultipleCompletableWithoutTransaction() {
+ final PutContentValuesStub putStub = PutContentValuesStub.newPutStubForMultipleContentValues(false);
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .contentValues(putStub.contentValues)
+ .withPutResolver(putStub.putResolver)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForMultipleContentValues(completable);
+ }
+
+ @Test
public void shouldFinishTransactionIfExceptionHasOccurredBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -241,6 +272,49 @@ public void shouldFinishTransactionIfExceptionHasOccurredSingle() {
}
@Test
+ public void shouldFinishTransactionIfExceptionHasOccurredCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ //noinspection unchecked
+ final PutResolver<ContentValues> putResolver = mock(PutResolver.class);
+
+ final List<ContentValues> contentValues = singletonList(mock(ContentValues.class));
+
+ when(putResolver.performPut(same(storIOSQLite), any(ContentValues.class)))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final TestSubscriber<PutResults<ContentValues>> testSubscriber = new TestSubscriber<PutResults<ContentValues>>();
+
+ new PreparedPutContentValuesIterable.Builder(storIOSQLite, contentValues)
+ .withPutResolver(putResolver)
+ .useTransaction(true)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ verify(internal).beginTransaction();
+ verify(internal, never()).setTransactionSuccessful();
+ verify(internal).endTransaction();
+
+ verify(storIOSQLite).lowLevel();
+ verify(putResolver).performPut(same(storIOSQLite), any(ContentValues.class));
+ verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
+ }
+
+ @Test
public void verifyBehaviorInCaseOfExceptionWithoutTransactionBlocking() {
final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
@@ -353,4 +427,44 @@ public void verifyBehaviorInCaseOfExceptionWithoutTransactionSingle() {
verify(putResolver).performPut(same(storIOSQLite), any(ContentValues.class));
verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
}
+
+ @Test
+ public void verifyBehaviorInCaseOfExceptionWithoutTransactionCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ //noinspection unchecked
+ final PutResolver<ContentValues> putResolver = mock(PutResolver.class);
+
+ final List<ContentValues> contentValues = singletonList(mock(ContentValues.class));
+
+ when(putResolver.performPut(same(storIOSQLite), any(ContentValues.class)))
+ .thenThrow(new IllegalStateException("test exception"));
+
+ final TestSubscriber<PutResults<ContentValues>> testSubscriber = new TestSubscriber<PutResults<ContentValues>>();
+
+ new PreparedPutContentValuesIterable.Builder(storIOSQLite, contentValues)
+ .withPutResolver(putResolver)
+ .useTransaction(false)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+ assertThat(cause).hasMessage("test exception");
+
+ // Main check of this test
+ verify(internal, never()).endTransaction();
+
+ verify(storIOSQLite).lowLevel();
+ verify(putResolver).performPut(same(storIOSQLite), any(ContentValues.class));
+ verifyNoMoreInteractions(storIOSQLite, internal, putResolver);
+ }
}
View
15 ...est/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutContentValuesTest.java
@@ -2,6 +2,7 @@
import org.junit.Test;
+import rx.Completable;
import rx.Observable;
import rx.Single;
@@ -48,4 +49,18 @@ public void putContentValuesSingle() {
putStub.verifyBehaviorForOneContentValues(putResultSingle);
}
+
+ @Test
+ public void putContentValuesCompletable() {
+ final PutContentValuesStub putStub = PutContentValuesStub.newPutStubForOneContentValues();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .contentValues(putStub.contentValues.get(0))
+ .withPutResolver(putStub.putResolver)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForOneContentValues(completable);
+ }
}
View
62 ...e/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PreparedPutObjectTest.java
@@ -7,6 +7,7 @@
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;
@@ -64,6 +65,20 @@ public void shouldPutObjectWithoutTypeMappingAsSingle() {
putStub.verifyBehaviorForOneObject(putResultSingle);
}
+
+ @Test
+ public void shouldPutObjectWithoutTypeMappingAsCompetable() {
+ final PutObjectsStub putStub = PutObjectsStub.newPutStubForOneObjectWithoutTypeMapping();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .object(putStub.items.get(0))
+ .withPutResolver(putStub.putResolver)
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForOneObject(completable);
+ }
}
public static class WithTypeMapping {
@@ -106,6 +121,19 @@ public void shouldPutObjectWithTypeMappingAsSingle() {
putStub.verifyBehaviorForOneObject(putResultSingle);
}
+
+ @Test
+ public void shouldPutObjectWithTypeMappingAsCompletable() {
+ final PutObjectsStub putStub = PutObjectsStub.newPutStubForOneObjectWithTypeMapping();
+
+ final Completable completable = putStub.storIOSQLite
+ .put()
+ .object(putStub.items.get(0))
+ .prepare()
+ .asRxComletable();
+
+ putStub.verifyBehaviorForOneObject(completable);
+ }
}
public static class TypeMappingError {
@@ -204,5 +232,39 @@ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutAffectingDbSingle(
verify(internal).typeMapping(Object.class);
verifyNoMoreInteractions(storIOSQLite, internal);
}
+
+ @Test
+ public void shouldThrowExceptionIfNoTypeMappingWasFoundWithoutAffectingDbCompletable() {
+ final StorIOSQLite storIOSQLite = mock(StorIOSQLite.class);
+ final StorIOSQLite.Internal internal = mock(StorIOSQLite.Internal.class);
+
+ when(storIOSQLite.lowLevel()).thenReturn(internal);
+
+ final Object object = new Object();
+
+ final TestSubscriber<PutResult> testSubscriber = new TestSubscriber<PutResult>();
+
+ new PreparedPutObject.Builder<Object>(storIOSQLite, object)
+ .prepare()
+ .asRxComletable()
+ .subscribe(testSubscriber);
+
+ testSubscriber.awaitTerminalEvent();
+ testSubscriber.assertNoValues();
+ testSubscriber.assertError(StorIOException.class);
+
+ //noinspection ThrowableResultOfMethodCallIgnored
+ StorIOException expected = (StorIOException) testSubscriber.getOnErrorEvents().get(0);
+
+ IllegalStateException cause = (IllegalStateException) expected.getCause();
+
+ assertThat(cause).hasMessage("Object does not have type mapping: " +
+ "object = " + object + ", object.class = " + object.getClass() + ", " +
+ "db was not affected by this operation, please add type mapping for this type");
+
+ verify(storIOSQLite).lowLevel();
+ verify(internal).typeMapping(Object.class);
+ verifyNoMoreInteractions(storIOSQLite, internal);
+ }
}
}
View
10 ...te/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PutContentValuesStub.java
@@ -10,6 +10,7 @@
import java.util.ArrayList;
import java.util.List;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.functions.Action1;
@@ -102,6 +103,10 @@ public void call(PutResults<ContentValues> putResults) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForMultipleContentValues(@NonNull Completable completable) {
+ verifyBehaviorForMultipleContentValues(completable.<PutResults<ContentValues>>toObservable());
+ }
+
void verifyBehaviorForMultipleContentValues(@NonNull Single<PutResults<ContentValues>> putResultsSingle) {
new ObservableBehaviorChecker<PutResults<ContentValues>>()
.observable(putResultsSingle.toObservable())
@@ -115,6 +120,7 @@ public void call(PutResults<ContentValues> putResults) {
.checkBehaviorOfObservable();
}
+
void verifyBehaviorForOneContentValues(@NonNull PutResult putResult) {
verifyBehaviorForMultipleContentValues(PutResults.newInstance(singletonMap(contentValues.get(0), putResult)));
}
@@ -145,6 +151,10 @@ public void call(PutResult putResult) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForOneContentValues(@NonNull Completable completable) {
+ verifyBehaviorForOneContentValues(completable.<PutResult>toObservable());
+ }
+
private void verifyTransactionBehavior() {
if (useTransaction) {
verify(internal, times(1)).beginTransaction();
View
9 ...o-sqlite/src/test/java/com/pushtorefresh/storio/sqlite/operations/put/PutObjectsStub.java
@@ -15,6 +15,7 @@
import java.util.List;
import java.util.Map;
+import rx.Completable;
import rx.Observable;
import rx.Single;
import rx.functions.Action1;
@@ -187,6 +188,10 @@ public void call(PutResults<TestItem> testItemPutResults) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForMultipleObjects(@NonNull Completable completable) {
+ verifyBehaviorForMultipleObjects(completable.<PutResults<TestItem>>toObservable());
+ }
+
void verifyBehaviorForOneObject(@NonNull PutResult putResult) {
verifyBehaviorForMultipleObjects(PutResults.newInstance(singletonMap(items.get(0), putResult)));
}
@@ -217,6 +222,10 @@ public void call(PutResult putResult) {
.checkBehaviorOfObservable();
}
+ void verifyBehaviorForOneObject(@NonNull Completable completable) {
+ verifyBehaviorForOneObject(completable.<PutResult>toObservable());
+ }
+
private void verifyTransactionBehavior() {
if (useTransaction) {
verify(internal, times(1)).beginTransaction();

0 comments on commit 52c1883

Please sign in to comment.
Something went wrong with that request. Please try again.