Permalink
Browse files

Add RxJava2 Adapter

  • Loading branch information...
ouattararomuald committed Jan 10, 2019
1 parent 67358f2 commit fd20997a82d6dfaa1acba4a6cb6e62107da5ec5b
Showing with 2,456 additions and 4 deletions.
  1. +2 −1 README.md
  2. +1 −0 build.gradle
  3. +1 −0 sample/build.gradle
  4. +28 −3 sample/src/main/kotlin/com/ouattararomuald/sample/Main.kt
  5. +12 −0 sample/src/main/kotlin/com/ouattararomuald/sample/RssReader.kt
  6. +76 −0 sample/src/test/kotlin/com/ouattararomuald/sample/RealFeedTest.kt
  7. +9 −0 sample/src/test/kotlin/com/ouattararomuald/sample/RssReader.kt
  8. +1 −0 settings.gradle
  9. +2 −0 syndication-rxjava2-adapter/.gitignore
  10. +71 −0 syndication-rxjava2-adapter/README.md
  11. +36 −0 syndication-rxjava2-adapter/build.gradle
  12. +3 −0 syndication-rxjava2-adapter/gradle.properties
  13. +112 −0 ...on-rxjava2-adapter/src/main/kotlin/com/ouattararomuald/adapter/rxjava2/CallEnqueueObservable.java
  14. +95 −0 ...on-rxjava2-adapter/src/main/kotlin/com/ouattararomuald/adapter/rxjava2/CallExecuteObservable.java
  15. +6 −0 syndication-rxjava2-adapter/src/main/kotlin/com/ouattararomuald/adapter/rxjava2/Parser.java
  16. +68 −0 ...ation-rxjava2-adapter/src/main/kotlin/com/ouattararomuald/adapter/rxjava2/RxJava2CallAdapter.java
  17. +82 −0 ...-rxjava2-adapter/src/main/kotlin/com/ouattararomuald/adapter/rxjava2/RxJava2CallAdapterFactory.kt
  18. +81 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/AsyncTest.java
  19. +82 −0 ...cation-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/CancelDisposeTest.java
  20. +60 −0 ...on-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/CancelDisposeTestSync.java
  21. +156 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/Data.kt
  22. +116 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/FlowableTest.java
  23. +152 −0 ...ion-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/FlowableThrowingTest.java
  24. +116 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/MaybeTest.java
  25. +136 −0 ...cation-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/MaybeThrowingTest.java
  26. +127 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/ObservableTest.java
  27. +128 −0 ...n-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/RecordingMaybeObserver.java
  28. +134 −0 ...cation-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/RecordingObserver.java
  29. +125 −0 ...-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/RecordingSingleObserver.java
  30. +151 −0 ...tion-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/RecordingSubscriber.java
  31. +37 −0 ...n-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/RxJavaPluginsResetRule.java
  32. +117 −0 syndication-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/SingleTest.java
  33. +133 −0 ...ation-rxjava2-adapter/src/test/kotlin/com/ouattararomuald/adapter/rxjava2/SingleThrowingTest.java
@@ -34,7 +34,8 @@ By default only `RssFeed` and `AtomFeed` are accepted as return type.

If you would like to do things asynchronously then take a look to existing adapters in this repo.

**kotlin-coroutines-adapter** for example let you return `Deferred<RssFeed>` or `Deferred<AtomFeed>`.
- **kotlin-coroutines-adapter** for example let you return `Deferred<RssFeed>` or `Deferred<AtomFeed>`.
- **rxjava2-adapter** let you return [RxJava 2.x](https://github.com/ReactiveX/RxJava) types (`Flowable`, `Maybe`, `Single`).

## Syndication specifications

@@ -21,6 +21,7 @@ buildscript {
],
'simpleXml': 'org.simpleframework:simple-xml:2.7.1',
'mockito': 'org.mockito:mockito-core:2.23.4',
'rxjava2': 'io.reactivex.rxjava2:rxjava:2.2.5',
'truth': 'com.google.truth:truth:0.42'
]

@@ -14,6 +14,7 @@ sourceSets {
dependencies {
implementation deps.kotlin.stdlib
implementation project(':syndication-feed')
implementation project(':syndication-rxjava2-adapter')
implementation project(':syndication-kotlin-coroutines-adapter')

testImplementation deps.junit.api
@@ -1,6 +1,7 @@
package com.ouattararomuald.sample

import com.ouattararomuald.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import com.ouattararomuald.adapter.rxjava2.RxJava2CallAdapterFactory
import com.ouattararomuald.syndication.Syndication
import kotlinx.coroutines.runBlocking

@@ -10,15 +11,39 @@ fun main() = runBlocking {
callFactory = CoroutineCallAdapterFactory()
)

val reader = syndicationReader.create(com.ouattararomuald.sample.RssReader::class.java)
val reader = syndicationReader.create(RssReader::class.java)
println(reader.read().await())

val syndicationReader2 = Syndication(
url = "https://www.lequipe.fr/rss/actu_rss.xml"
)

val reader2 = syndicationReader2.create(com.ouattararomuald.sample.RssReader::class.java)
val reader2 = syndicationReader2.create(RssReader::class.java)
println(reader2.readSync())

println("")
println("=====RxJava2 Adapter=====")

val syndicationReader3 = Syndication(
url = "https://www.lequipe.fr/rss/actu_rss.xml",
callFactory = RxJava2CallAdapterFactory()
)

val reader3 = syndicationReader3.create(RssReader::class.java)
reader3.readFlowable().subscribe { rssFeed ->
println(rssFeed)
}

reader3.readMaybe().subscribe { rssFeed ->
println(rssFeed)
}

reader3.readObservable().subscribe { rssFeed ->
println(rssFeed)
}

reader3.readSingle().subscribe { rssFeed ->
println(rssFeed)
}

println()
}
@@ -1,11 +1,23 @@
package com.ouattararomuald.sample

import com.ouattararomuald.syndication.rss.RssFeed
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Observable
import io.reactivex.Single
import kotlinx.coroutines.Deferred

interface RssReader {

fun read(): Deferred<RssFeed>

fun readSync(): RssFeed

fun readFlowable(): Flowable<RssFeed>

fun readMaybe(): Maybe<RssFeed>

fun readObservable(): Observable<RssFeed>

fun readSingle(): Single<RssFeed>
}
@@ -1,7 +1,11 @@
package com.ouattararomuald.sample

import com.google.common.truth.Truth.assertThat
import com.ouattararomuald.adapter.rxjava2.RxJava2CallAdapterFactory
import com.ouattararomuald.syndication.Syndication
import com.ouattararomuald.syndication.rss.RssFeed
import io.reactivex.observers.TestObserver
import io.reactivex.subscribers.TestSubscriber
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.jupiter.api.AfterEach
@@ -69,4 +73,76 @@ class RealFeedTest {
assertThat(reader.readRss()).isNotNull()
}
}

@Test fun `flowable rss feeds`() {
server.enqueue(
MockResponse()
.setResponseCode(200)
.setBody(Data.RSS_SENAT)
)

server.runTests {
val baseUrl = server.url(FAKE_URL)
val syndication = Syndication(
url = baseUrl.toString(),
callFactory = RxJava2CallAdapterFactory.create()
)
val reader = syndication.create(RssReader::class.java)

val subscriber = TestSubscriber<RssFeed>()
reader.readFlowableRss().subscribe(subscriber)
subscriber.assertComplete()
subscriber.assertNoErrors()
subscriber.assertValueCount(1)
subscriber.assertValue { it.channel.title == "Sénat - derniers rapports" }
}
}

@Test fun `maybe rss feeds`() {
server.enqueue(
MockResponse()
.setResponseCode(200)
.setBody(Data.RSS_SENAT)
)

server.runTests {
val baseUrl = server.url(FAKE_URL)
val syndication = Syndication(
url = baseUrl.toString(),
callFactory = RxJava2CallAdapterFactory.create()
)
val reader = syndication.create(RssReader::class.java)

val observer = TestObserver<RssFeed>()
reader.readMaybeRss().subscribe(observer)
observer.assertComplete()
observer.assertNoErrors()
observer.assertValueCount(1)
observer.assertValue { it.channel.title == "Sénat - derniers rapports" }
}
}

@Test fun `single rss feeds`() {
server.enqueue(
MockResponse()
.setResponseCode(200)
.setBody(Data.RSS_SENAT)
)

server.runTests {
val baseUrl = server.url(FAKE_URL)
val syndication = Syndication(
url = baseUrl.toString(),
callFactory = RxJava2CallAdapterFactory.create()
)
val reader = syndication.create(RssReader::class.java)

val observer = TestObserver<RssFeed>()
reader.readSingleRss().subscribe(observer)
observer.assertComplete()
observer.assertNoErrors()
observer.assertValueCount(1)
observer.assertValue { it.channel.title == "Sénat - derniers rapports" }
}
}
}
@@ -2,10 +2,19 @@ package com.ouattararomuald.sample

import com.ouattararomuald.syndication.atom.AtomFeed
import com.ouattararomuald.syndication.rss.RssFeed
import io.reactivex.Flowable
import io.reactivex.Maybe
import io.reactivex.Single

interface RssReader {

fun readAtom(): AtomFeed

fun readRss(): RssFeed

fun readFlowableRss(): Flowable<RssFeed>

fun readMaybeRss(): Maybe<RssFeed>

fun readSingleRss(): Single<RssFeed>
}
@@ -1,5 +1,6 @@
rootProject.name = 'syndication'
include 'syndication-feed'
include 'syndication-kotlin-coroutines-adapter'
include 'syndication-rxjava2-adapter'
include 'sample'

@@ -0,0 +1,2 @@
/build
/out
@@ -0,0 +1,71 @@
[![](https://img.shields.io/maven-central/v/com.ouattararomuald/syndication-rxjava2-adapter.svg)](https://search.maven.org/search?q=g:com.ouattararomuald%20a:syndication-rxjava2-adapter)
[![](https://img.shields.io/nexus/s/https/oss.sonatype.org/com.ouattararomuald/syndication-rxjava2-adapter.svg)](https://oss.sonatype.org/content/repositories/snapshots/)

# RxJava2 Adapter

An adapter for adapting [RxJava 2.x](https://github.com/ReactiveX/RxJava) types.

Available types:

- `Flowable<T>` with `T` being `AtomFeed` or `RssFeed`.
- `Maybe<T>` with `T` being `AtomFeed` or `RssFeed`.
- `Single<T>` with `T` being `AtomFeed` or `RssFeed`.

## Usage

Pass `RxJava2CallAdapterFactory` as parameter to `Syndication`.

```kotlin
val syndicationReader = Syndication(
url = "https://www.lequipe.fr/rss/actu_rss.xml",
callFactory = RxJava2CallAdapterFactory.create()
)
```

create and interface like the one below

```kotlin
interface RssReader {
fun readFlowable(): Flowable<RssFeed>
fun readMaybe(): Maybe<RssFeed>
fun readSingle(): Single<RssFeed>
}
```

then let `Syndication` class generates an implementation of that interface `RssReader`:

```kotlin
val reader = syndicationReader.create(RssReader::class.java)
reader.readFlowable().subscribe { rssFeed -> /* do something */ }
reader.readMaybe().subscribe { rssFeed -> /* do something */ }
reader.readSingle().subscribe { rssFeed -> /* do something */ }
```

By default all reactive types execute their requests synchronously. There are multiple ways to control the threading on which a request occurs:

- Call `subscribeOn` on the returned reactive type with a `Scheduler` of your choice.
- Use `createAsync()` when creating the factory which will use OkHttp's internal thread pool.
- Use `createWithScheduler(Scheduler)` to supply a default subscription `Scheduler`.

## Download

Download the [latest JAR](https://search.maven.org/search?q=g:com.ouattararomuald%20AND%20a:syndication-rxjava2-adapter) or grab via Gradle:

```gradle
implementation 'com.ouattararomuald:syndication-rxjava2-adapter:0.1.0-rc.1'
```

or Maven:

```xml
<dependency>
<groupId>com.ouattararomuald</groupId>
<artifactId>syndication-rxjava2-adapter</artifactId>
<version>0.1.0-rc.1</version>
</dependency>
```

Snapshots of the development version are available in [Sonatype's snapshots repository](https://oss.sonatype.org/content/repositories/snapshots/).
@@ -0,0 +1,36 @@
apply plugin: 'java-library'
apply plugin: 'org.jetbrains.kotlin.jvm'

test {
useJUnitPlatform()
}

sourceSets {
main.kotlin.srcDirs += 'src/main/kotlin'
main.java.srcDirs += 'src/main/kotlin'
test.kotlin.srcDirs += 'src/test/kotlin'
test.java.srcDirs += 'src/test/kotlin'
}

dependencies {
implementation deps.kotlin.stdlib
api project(':syndication-feed')

api deps.rxjava2

testImplementation deps.junit.api
testRuntimeOnly deps.junit.engine
testImplementation deps.mockWebServer
testImplementation deps.truth
testImplementation deps.mockito
}

compileTestKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8
}

compileTestKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8
}

apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
@@ -0,0 +1,3 @@
POM_ARTIFACT_ID=syndication-rxjava2-adapter
POM_NAME=An adapter for adapter RxJava 2.x types.
POM_PACKAGING=aar
Oops, something went wrong.

0 comments on commit fd20997

Please sign in to comment.