Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part1: Forward notifications between StorIOSQLite v1 and v3 #876

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ ext.libraries = [
// Core libraries
supportAnnotations : 'com.android.support:support-annotations:' + supportLibsVersion,

rxJava : 'io.reactivex:rxjava:1.2.1',
rxJava2 : 'io.reactivex.rxjava2:rxjava:2.1.6',
rxAndroid2 : 'io.reactivex.rxjava2:rxandroid:2.0.1',
kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
Expand All @@ -73,6 +74,9 @@ ext.libraries = [
storIOContentResolverAnnotationsProcessor: project(':storio-content-resolver-annotations-processor'),
storIOTestCommon : project(':storio-test-common'),

// StorIO old versions
storIOSQLite1 : 'com.pushtorefresh.storio:sqlite:1.13.0',

// Libraries for tests and sample app
junit : 'junit:junit:4.12',
assertJ : 'org.assertj:assertj-core:3.9.0', // http://joel-costigliola.github.io/assertj/assertj-core-news.html
Expand Down
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ include ':storio-sqlite-annotations-processor-test'
include ':storio-content-resolver-annotations-processor'
include ':storio-content-resolver-annotations-processor-test'

include ':storio-sqlite-interop1to3'

include ':storio-test-without-rxjava'

include ':storio-basic-sample-app'
Expand Down
35 changes: 35 additions & 0 deletions storio-sqlite-interop1to3/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion rootProject.ext.compileSdkVersion

defaultConfig {
versionName VERSION_NAME
versionCode Integer.parseInt(VERSION_CODE)
minSdkVersion rootProject.ext.minSdkVersion
}

packagingOptions {
exclude 'LICENSE.txt' // multiple libs have this file -> cause build error
}
}

dependencies {
implementation libraries.storIOSQLite1
implementation libraries.storIOSQLite

compileOnly libraries.rxJava
compileOnly libraries.rxJava2
testImplementation libraries.rxJava
testImplementation libraries.rxJava2

testImplementation libraries.junit
testImplementation libraries.kotlinStdLib
testImplementation libraries.mockitoKotlin
testImplementation libraries.assertJ
}

apply from: '../gradle/checkstyle.gradle'
apply from: '../gradle/jacoco-android.gradle'
apply from: '../gradle/publish-android-lib.gradle'
3 changes: 3 additions & 0 deletions storio-sqlite-interop1to3/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
POM_NAME=storio-sqlite-interop1to3
POM_ARTIFACT_ID=storio-sqlite-interop1to3
POM_PACKAGING=jar
2 changes: 2 additions & 0 deletions storio-sqlite-interop1to3/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.pushtorefresh.storio3.sqlite.interop1to3" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.pushtorefresh.storio3.sqlite.interop1to3;

import android.support.annotation.NonNull;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.BackpressureStrategy;
import io.reactivex.functions.Consumer;
import rx.functions.Action1;

public class StorIOSQLite1To3 {

private final Set<com.pushtorefresh.storio.sqlite.Changes> forwardedChanges1 = Collections.newSetFromMap(
new ConcurrentHashMap<com.pushtorefresh.storio.sqlite.Changes, Boolean>()
);

private final Set<com.pushtorefresh.storio3.sqlite.Changes> forwardedChanges3 = Collections.newSetFromMap(
new ConcurrentHashMap<com.pushtorefresh.storio3.sqlite.Changes, Boolean>()
);

public void forwardNotifications(
@NonNull final com.pushtorefresh.storio.sqlite.StorIOSQLite sqlite1,
@NonNull final com.pushtorefresh.storio3.sqlite.StorIOSQLite sqlite3
) {
com.pushtorefresh.storio.internal.Environment.throwExceptionIfRxJavaIsNotAvailable(
"forwardNotifications() requires rxJava2"
);
com.pushtorefresh.storio3.internal.Environment.throwExceptionIfRxJava2IsNotAvailable(
"forwardNotifications() requires rxJava2"
);

sqlite1.observeChanges()
.subscribe(new Action1<com.pushtorefresh.storio.sqlite.Changes>() {
@Override
public void call(@NonNull com.pushtorefresh.storio.sqlite.Changes changes1) {
if (!forwardedChanges1.remove(changes1)) { // Check to prevent cyclic forwarding.
final com.pushtorefresh.storio3.sqlite.Changes changes3ToForward
= convertToV3(changes1);
forwardedChanges3.add(changes3ToForward);
sqlite3.lowLevel().notifyAboutChanges(changes3ToForward);
}
}
});

sqlite3.observeChanges(BackpressureStrategy.BUFFER)
.subscribe(new Consumer<com.pushtorefresh.storio3.sqlite.Changes>() {
@Override
public void accept(com.pushtorefresh.storio3.sqlite.Changes changes3) throws Exception {
if (!forwardedChanges3.remove(changes3)) { // Check to prevent cyclic forwarding.
final com.pushtorefresh.storio.sqlite.Changes changes1ToForward
= convertToV1(changes3);
forwardedChanges1.add(changes1ToForward);
sqlite1.lowLevel().notifyAboutChanges(changes1ToForward);
}
}
});
}

@NonNull
private com.pushtorefresh.storio.sqlite.Changes convertToV1(
@NonNull com.pushtorefresh.storio3.sqlite.Changes changes3
) {
return com.pushtorefresh.storio.sqlite.Changes.newInstance(
changes3.affectedTables(),
changes3.affectedTags()
);
}

@NonNull
private com.pushtorefresh.storio3.sqlite.Changes convertToV3(
@NonNull com.pushtorefresh.storio.sqlite.Changes changes1
) {
return com.pushtorefresh.storio3.sqlite.Changes.newInstance(
changes1.affectedTables(),
changes1.affectedTags()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.pushtorefresh.storio3.sqlite.interop1to3

import com.nhaarman.mockito_kotlin.mock
import io.reactivex.BackpressureStrategy
import org.junit.Before
import org.junit.Test
import com.pushtorefresh.storio.sqlite.Changes as Changes1
import com.pushtorefresh.storio.sqlite.StorIOSQLite as StorIOSQLite1
import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite as DefaultStorIOSQLite1
import com.pushtorefresh.storio3.sqlite.Changes as Changes3
import com.pushtorefresh.storio3.sqlite.StorIOSQLite as StorIOSQLite3
import com.pushtorefresh.storio3.sqlite.impl.DefaultStorIOSQLite as DefaultStorIOSQLite3
import io.reactivex.subscribers.TestSubscriber as TestSubscriberRx2
import rx.observers.TestSubscriber as TestSubscriberRx1

class StorIOSQLite1To3Test {

val observer1 = TestSubscriberRx1.create<Changes1>()

val observer3 = TestSubscriberRx2.create<Changes3>()

lateinit var storIOSQLite1: StorIOSQLite1

lateinit var storIOSQLite3: StorIOSQLite3

lateinit var changes1WithTags: Changes1

lateinit var changes1WithoutTags: Changes1

lateinit var changes3WithTags: Changes3

lateinit var changes3WithoutTags: Changes3

@Before
fun `before each test`() {
storIOSQLite1 = DefaultStorIOSQLite1.builder()
.sqliteOpenHelper(mock())
.defaultScheduler(null)
.build()
storIOSQLite3 = DefaultStorIOSQLite3.builder()
.sqliteOpenHelper(mock())
.defaultRxScheduler(null)
.build()
val interop = StorIOSQLite1To3()
interop.forwardNotifications(storIOSQLite1, storIOSQLite3)

storIOSQLite1.observeChanges().subscribe(observer1)
storIOSQLite3.observeChanges(BackpressureStrategy.BUFFER).subscribe(observer3)

val tables = HashSet<String>()
tables.add("table1")
tables.add("table2")

val tags = HashSet<String>()
tags.add("tag1")
tags.add("tag2")

changes1WithTags = Changes1.newInstance(tables, tags)
changes3WithTags = Changes3.newInstance(tables, tags)

changes1WithoutTags = Changes1.newInstance(tables, null as Collection<String>?)
changes3WithoutTags = Changes3.newInstance(tables, null as Collection<String>?)
}

@Test
fun `forwardNotifications should forward from 1 to 3 with tags`() {
storIOSQLite1.lowLevel().notifyAboutChanges(changes1WithTags)
observer1.assertValue(changes1WithTags)
observer3.assertValue(changes3WithTags)
}

@Test
fun `forwardNotifications should forward from 1 to 3 without tags`() {
storIOSQLite1.lowLevel().notifyAboutChanges(changes1WithoutTags)
observer1.assertValue(changes1WithoutTags)
observer3.assertValue(changes3WithoutTags)
}

@Test
fun `forwardNotifications should forward from 1 to 3 multiple`() {
storIOSQLite1.lowLevel().notifyAboutChanges(changes1WithTags)
observer1.assertValue(changes1WithTags)
observer3.assertValue(changes3WithTags)

storIOSQLite1.lowLevel().notifyAboutChanges(changes1WithTags)
observer1.assertValues(changes1WithTags, changes1WithTags)
observer3.assertValues(changes3WithTags, changes3WithTags)
}

@Test
fun `forwardNotifications should forward from 3 to 1 with tags`() {
storIOSQLite3.lowLevel().notifyAboutChanges(changes3WithTags)
observer1.assertValue(changes1WithTags)
observer3.assertValue(changes3WithTags)
}

@Test
fun `forwardNotifications should forward from 3 to 1 without tags`() {
storIOSQLite3.lowLevel().notifyAboutChanges(changes3WithoutTags)
observer1.assertValue(changes1WithoutTags)
observer3.assertValue(changes3WithoutTags)
}

@Test
fun `forwardNotifications should forward from 3 to 1 with multiple`() {
storIOSQLite3.lowLevel().notifyAboutChanges(changes3WithTags)
observer1.assertValue(changes1WithTags)
observer3.assertValue(changes3WithTags)

storIOSQLite3.lowLevel().notifyAboutChanges(changes3WithTags)
observer1.assertValues(changes1WithTags, changes1WithTags)
observer3.assertValues(changes3WithTags, changes3WithTags)
}
}