Skip to content

Commit

Permalink
Kotlin 1.3 and Kotlinx.Coroutines 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gildor committed Nov 4, 2018
1 parent f583759 commit 41473bf
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 70 deletions.
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# CHANGELOG

## Version 0.13.0-eap13 (2017-10-10)
## Version 1.0.0 (2018-11-03)

- kotlinx.coroutines 1.0.0
- Compiled against Kotlin 1.3.0

## Version 0.13.0-eap13 (2018-10-10)

- kotlinx.coroutines 0.30.2-eap13
- Compiled against Kotlin 1.3.0-rc-146

## Version 0.13.0 (2017-10-10)
## Version 0.13.0 (2018-10-10)

- [kotlinx.coroutines 0.30.2](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.30.2)
- Compiled against Kotlin 1.2.71

## Version 0.12.0-eap13 (2017-08-04) - Stable coroutines
## Version 0.12.0-eap13 (2018-08-04) - Stable coroutines

First version of kotlin-coroutines-retrofit based on stable coroutines API from Kotlin 1.3
Compiled against Kotlin 1.3-M1 and kotlinx.coroutines 0.24.0-eap13 (also based on stable API)
Expand Down
31 changes: 6 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,27 @@ This is a small library that provides the [Kotlin Coroutines](https://github.com

Based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation.

This branch uses stable version of Kotlin coroutines and work only on Kotlin 1.3 (including EAP builds)
New version of library (after 1.0.0) support only Kotlin 1.3

Kotlin 1.2 and experimental coroutines are not supported anymore, but you can use version `0.13.0` for old projects.

## Download

Download the [JAR](https://bintray.com/gildor/maven/kotlin-coroutines-retrofit#files/ru/gildor/coroutines/kotlin-coroutines-retrofit):

### If you use Kotlin 1.2: Version of the library based on experimental coroutines API

Gradle:

```groovy
compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.13.0'
```

Maven:getOrThrow

```xml
<dependency>
<groupId>ru.gildor.coroutines</groupId>
<artifactId>kotlin-coroutines-retrofit</artifactId>
<version>0.13.0</version>
</dependency>
```

### If you use Kotlin 1.3: Version based on stable coroutines API


Gradle:

```groovy
compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.13.0-eap13'
compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:1.0.0'
```

Maven:getOrThrow
Maven:

```xml
<dependency>
<groupId>ru.gildor.coroutines</groupId>
<artifactId>kotlin-coroutines-retrofit</artifactId>
<version>0.13.0-eap13</version>
<version>1.0.0</version>
</dependency>
```

Expand Down
7 changes: 3 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper

plugins {
id("org.jetbrains.kotlin.jvm") version "1.3.0-rc-146"
id("org.jetbrains.kotlin.jvm") version "1.3.0"
id("com.jfrog.bintray") version "1.8.4"
jacoco
`maven-publish`
id("org.jetbrains.dokka") version "0.9.16"
}

group = "ru.gildor.coroutines"
version = "0.13.0-eap13"
version = "1.0.0"
description = "Provides Kotlin Coroutines suspendable await() extensions for Retrofit Call"

repositories {
jcenter()
maven("http://dl.bintray.com/kotlin/kotlin-eap")
}

java {
Expand All @@ -35,7 +34,7 @@ java {

dependencies {
compile("org.jetbrains.kotlin:kotlin-stdlib")
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.2-eap13")
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0")
compile("com.squareup.retrofit2:retrofit:2.4.0")
testCompile("junit:junit:4.12")
}
Expand Down
75 changes: 37 additions & 38 deletions src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package ru.gildor.coroutines.retrofit

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
Expand All @@ -35,104 +35,105 @@ import ru.gildor.coroutines.retrofit.util.errorResponse

private const val DONE = "Done!"

@ExperimentalCoroutinesApi
class CallAwaitTest {
@Test
fun asyncSuccess() = testBlocking {
fun asyncSuccess() = runBlocking {
assertEquals(DONE, MockedCall(DONE).await())
}

@Test(expected = HttpException::class)
fun asyncHttpException() = testBlocking {
fun asyncHttpException() = runBlocking {
MockedCall<String>(error = HttpException(errorResponse<String>())).await()
}

@Test(expected = NullPointerException::class)
fun asyncNullBody() = testBlocking {
fun asyncNullBody() = runBlocking {
NullBodyCall<String>().await()
}

@Test(expected = IllegalArgumentException::class)
fun asyncException() = testBlocking {
fun asyncException() = runBlocking {
MockedCall<String>(exception = IllegalArgumentException("wrong get param")).await()
}

@Test
fun asyncResponseOk() = testBlocking {
fun asyncResponseOk() = runBlocking {
val result = MockedCall(DONE).awaitResponse()
assertEquals(DONE, result.body())
}

@Test
fun asyncResponseError() = testBlocking {
fun asyncResponseError() = runBlocking {
val result = MockedCall<String>(error = HttpException(errorResponse<String>(500))).awaitResponse()
assertEquals(500, result.code())
}

@Test
fun awaitRequestCancel() = testBlocking {
fun awaitRequestCancel() = runBlocking {
checkJobCancel { it.await() }
}

@Test
fun awaitResponseRequestCancel() = testBlocking {
fun awaitResponseRequestCancel() = runBlocking {
checkJobCancel { it.awaitResponse() }
}

@Test
fun awaitResultRequestCancel() = testBlocking {
fun awaitResultRequestCancel() = runBlocking {
checkJobCancel { it.awaitResult() }
}

@Test
fun requestCancelWithException() = testBlocking {
fun requestCancelWithException() = runBlocking {
checkRequestCancelWithException { it.awaitResponse() }
}

@Test
fun awaitRequestCancelWithException() = testBlocking {
fun awaitRequestCancelWithException() = runBlocking {
checkRequestCancelWithException { it.await() }
}

@Test
fun awaitResultCancelWithException() = testBlocking {
fun awaitResultCancelWithException() = runBlocking {
checkRequestCancelWithException { it.awaitResult() }
}

@Test(expected = IllegalArgumentException::class)
fun asyncResponseException() = testBlocking {
fun asyncResponseException() = runBlocking {
MockedCall<String>(exception = IllegalArgumentException()).awaitResponse()
}

@Test
fun awaitJobCancelWithException() = testBlocking {
fun awaitJobCancelWithException() = runBlocking {
checkJobCancelWithException { it.await() }
}

@Test
fun awaitResponseJobCancelWithException() = testBlocking {
fun awaitResponseJobCancelWithException() = runBlocking {
checkJobCancelWithException { it.awaitResponse() }
}

@Test
fun awaitResultJobCancelWithException() = testBlocking {
fun awaitResultJobCancelWithException() = runBlocking {
checkJobCancelWithException { it.awaitResult() }
}

@Test
fun asyncResponseNullBody() = testBlocking {
fun asyncResponseNullBody() = runBlocking {
val result = NullBodyCall<String>().awaitResponse()
assertNull(result.body())
}

@Test
fun asyncResponseNullableBody() = testBlocking {
fun asyncResponseNullableBody() = runBlocking {
//Check that we can call awaitResponse() on nullable body
val result = NullBodyCall<String?>().awaitResponse()
assertNull(result.body())
}

@Test
fun asyncResponseFailure() = testBlocking {
fun asyncResponseFailure() = runBlocking {
val exception = IllegalStateException()
try {
MockedCall<String>(exception = exception).awaitResult()
Expand All @@ -142,7 +143,7 @@ class CallAwaitTest {
}

@Test
fun asyncResultOk() = testBlocking {
fun asyncResultOk() = runBlocking {
val result = MockedCall(DONE).awaitResult()
when (result) {
is Result.Ok -> {
Expand All @@ -155,19 +156,19 @@ class CallAwaitTest {
}

@Test
fun asyncResultNullBody() = testBlocking {
fun asyncResultNullBody() = runBlocking {
val result = NullBodyCall<String>().awaitResult()
assertNull(result.getOrNull())
}

@Test(expected = NullPointerException::class)
fun asyncResultNullPointerForNullBody() = testBlocking {
fun asyncResultNullPointerForNullBody() = runBlocking {
val result = NullBodyCall<String>().awaitResult()
assertNull(result.getOrThrow())
}

@Test
fun asyncResultByType() = testBlocking {
fun asyncResultByType() = runBlocking {
val result = MockedCall(DONE).awaitResult()
when (result) {
is ResponseResult -> {
Expand All @@ -179,7 +180,7 @@ class CallAwaitTest {
}

@Test
fun resultOkTypes() = testBlocking {
fun resultOkTypes() = runBlocking {
val result = MockedCall(DONE).awaitResult()
if (result is ResponseResult) {
// Mocked raw response doesn't contain body, but we can check code
Expand All @@ -190,7 +191,7 @@ class CallAwaitTest {
}

@Test
fun resultErrorTypes() = testBlocking {
fun resultErrorTypes() = runBlocking {
val errorResponse = errorResponse<String>(500)
val httpException = HttpException(errorResponse)
val errorResult = MockedCall<String>(error = httpException).awaitResult()
Expand All @@ -209,7 +210,7 @@ class CallAwaitTest {
}

@Test
fun resultExceptionTypes() = testBlocking {
fun resultExceptionTypes() = runBlocking {
val exception = IllegalStateException()
val errorResult = MockedCall<String>(exception = exception).awaitResult()

Expand All @@ -222,7 +223,7 @@ class CallAwaitTest {


@Test
fun asyncResultError() = testBlocking {
fun asyncResultError() = runBlocking {
val error = HttpException(errorResponse<String>(500))
val result = MockedCall<String>(error = error).awaitResult()
when (result) {
Expand All @@ -238,7 +239,7 @@ class CallAwaitTest {
}

@Test
fun asyncResultException() = testBlocking {
fun asyncResultException() = runBlocking {
val exception = IllegalArgumentException("wrong argument")
val result = MockedCall<String>(exception = exception).awaitResult()
when (result) {
Expand All @@ -253,13 +254,13 @@ class CallAwaitTest {

private fun <T> checkRequestCancelWithException(
block: suspend (Call<String>) -> T
) = testBlocking {
) = runBlocking {
val request = MockedCall(
ok = DONE,
autoStart = false,
cancelException = IllegalStateException()
)
val async = async(coroutineContext, block = { block(request) })
val async = async(Dispatchers.Unconfined, block = { block(request) })
//We shouldn't crash on cancel exception
try {
assertFalse(request.isCanceled)
Expand All @@ -270,12 +271,12 @@ class CallAwaitTest {
}
}

private fun <T> checkJobCancelWithException(block: suspend (Call<String>) -> T) = testBlocking {
private fun <T> checkJobCancelWithException(block: suspend (Call<String>) -> T) = runBlocking {
val request = MockedCall<String>(
exception = IllegalArgumentException(),
autoStart = false
)
val result = async(coroutineContext) {
val result = async(Dispatchers.Unconfined) {
block(request)
}
result.cancel()
Expand All @@ -285,16 +286,14 @@ class CallAwaitTest {

private fun <T> checkJobCancel(
block: suspend (Call<String>) -> T
) = testBlocking {
) = runBlocking {
val request = MockedCall(DONE, autoStart = false)
val async = async(coroutineContext) { block(request) }
val async = async(Dispatchers.Unconfined) { block(request) }
assertFalse(request.isCanceled)
async.cancel()
assertTrue(request.isCanceled)
}
}

private fun testBlocking(block: suspend CoroutineScope.() -> Unit) {
runBlocking(Dispatchers.Unconfined, block)
}


0 comments on commit 41473bf

Please sign in to comment.