diff --git a/CHANGELOG.md b/CHANGELOG.md
index 662d08b..ab8a29c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,13 @@
# CHANGELOG
+## Version 0.12.0 (2017-08-04)
+
+- [kotlinx.coroutines 0.24.0](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.24.0)
+- Compiled against Kotlin 1.2.60
+
## Version 0.11.0 (2017-06-12)
-- [kotlinx.coroutines 0.23.1](https://github.com/Kotlin/kotlinx.coroutines/releases/)
+- [kotlinx.coroutines 0.23.1](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.23.1)
- Compiled against Kotlin 1.2.41
Thanks to [Thomas Schmidt](https://github.com/bohsen) for contribution
diff --git a/README.md b/README.md
index c021439..2db28b0 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,11 @@
This is a small library that provides the [Kotlin Coroutines](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md) [suspending](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#suspending-functions) extension `Call.await()` for [Retrofit 2](https://github.com/square/retrofit)
-Based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation
+Based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation.
+
+This branch uses Kotlin experimental package `kotlin.coroutines.experimental` (pre-1.3).
+
+Migration to package stable `kotlin.coroutines` package is planned and work in progress.
## Download
Download the [JAR](https://bintray.com/gildor/maven/kotlin-coroutines-retrofit#files/ru/gildor/coroutines/kotlin-coroutines-retrofit):
@@ -14,16 +18,16 @@ Download the [JAR](https://bintray.com/gildor/maven/kotlin-coroutines-retrofit#f
Gradle:
```groovy
-compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.11.0'
+compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.12.0'
```
-Maven:
+Maven:getOrThrow
```xml
ru.gildor.coroutines
kotlin-coroutines-retrofit
- 0.11.0
+ 0.12.0
```
@@ -49,7 +53,7 @@ In case of an HTTP error or an invocation exception `await()` throws an exceptio
```kotlin
// You can use retrofit suspended extension inside any coroutine block
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
try {
// Wait (suspend) for result
val user: User = api.getUser("username").await()
@@ -76,7 +80,7 @@ In case of an invocation exception `awaitResponse()` throws an exception
```kotlin
// You can use retrofit suspended extension inside any coroutine block
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
try {
// Wait (suspend) for response
val response: Response = api.getUser("username").awaitResponse()
@@ -100,7 +104,7 @@ fun Call.awaitResult(): Result
```
```kotlin
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
// Wait (suspend) for Result
val result: Result = api.getUser("username").awaitResult()
// Check result type
@@ -118,7 +122,7 @@ fun main(args: Array) = runBlocking {
Also, `Result` has a few handy extension functions that allow to avoid `when` block matching:
```kotlin
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
val result: User = api.getUser("username").awaitResult()
//Return value for success or null for any http error or exception
@@ -138,7 +142,7 @@ All `Result` classes also implemented one or both interfaces: `ResponseResult` a
You can use them for access to shared properties of different classes from `Result`
```kotlin
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
val result: User = api.getUser("username").awaitResult()
//Result.Ok and Result.Error both implement ResponseResult
@@ -162,7 +166,7 @@ extensions `.await()` and `.awaitResult()` are available only for
non-nullable `Call` or platform `Call` body types:
```kotlin
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
val user: Call = api.getUser("username")
val userOrNull: Call = api.getUserOrNull("username")
@@ -194,7 +198,7 @@ You can do that by wrapping calls with `kotlinx.coroutines` [async()](https://ko
```kotlin
-fun main(args: Array) = runBlocking {
+fun main(args: Array): Unit = runBlocking {
val users = listOf("user1", "user2", "user3")
.map { username ->
// Pass any coroutine context that fits better for your case
diff --git a/build.gradle.kts b/build.gradle.kts
index 14e1574..f09f352 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -12,15 +12,15 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
plugins {
- id("org.jetbrains.kotlin.jvm") version "1.2.41"
- id("com.jfrog.bintray") version "1.7.3"
+ id("org.jetbrains.kotlin.jvm") version "1.2.60"
+ 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.11.0"
+version = "0.12.0"
description = "Provides Kotlin Coroutines suspendable await() extensions for Retrofit Call"
repositories {
@@ -34,7 +34,7 @@ java {
dependencies {
compile("org.jetbrains.kotlin:kotlin-stdlib")
- compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.1")
+ compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0")
compile("com.squareup.retrofit2:retrofit:2.4.0")
testCompile("junit:junit:4.12")
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 736fb7d..91ca28c 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 73bb13d..6d2395a 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,6 @@
+# suppress inspection "UnusedProperty" for whole file
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
diff --git a/src/main/kotlin/ru/gildor/coroutines/retrofit/CallAwait.kt b/src/main/kotlin/ru/gildor/coroutines/retrofit/CallAwait.kt
index 5b69a38..1d9d95b 100644
--- a/src/main/kotlin/ru/gildor/coroutines/retrofit/CallAwait.kt
+++ b/src/main/kotlin/ru/gildor/coroutines/retrofit/CallAwait.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Andrey Mischenko
+ *
+ * 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 ru.gildor.coroutines.retrofit
import kotlinx.coroutines.experimental.CancellableContinuation
@@ -8,7 +24,7 @@ import retrofit2.HttpException
import retrofit2.Response
/**
- * Suspend extension that allows suspend [Call] inside coroutine.
+ * Suspend extension that allows suspend [Call] inside of a coroutine.
*
* @return Result of request or throw exception
*/
@@ -20,7 +36,7 @@ public suspend fun Call.await(): T {
val body = response.body()
if (body == null) {
continuation.resumeWithException(
- NullPointerException("Response body is null: $response")
+ NullPointerException("Response body is null: $response")
)
} else {
continuation.resume(body)
@@ -68,23 +84,24 @@ public suspend fun Call.awaitResponse(): Response {
* Suspend extension that allows suspend [Call] inside coroutine.
*
* @return sealed class [Result] object that can be
- * casted to [Result.Ok] (success) or [Result.Error] (HTTP error) and [Result.Exception] (other errors)
+ * casted to [Result.Ok] (success) or [Result.Error] (HTTP error)
+ * and [Result.Exception] (other errors)
*/
public suspend fun Call.awaitResult(): Result {
return suspendCancellableCoroutine { continuation ->
enqueue(object : Callback {
override fun onResponse(call: Call?, response: Response) {
continuation.resume(
- if (response.isSuccessful) {
- val body = response.body()
- if (body == null) {
- Result.Exception(NullPointerException("Response body is null"))
- } else {
- Result.Ok(body, response.raw())
- }
+ if (response.isSuccessful) {
+ val body = response.body()
+ if (body == null) {
+ Result.Exception(NullPointerException("Response body is null"))
} else {
- Result.Error(HttpException(response), response.raw())
+ Result.Ok(body, response.raw())
}
+ } else {
+ Result.Error(HttpException(response), response.raw())
+ }
)
}
diff --git a/src/main/kotlin/ru/gildor/coroutines/retrofit/Result.kt b/src/main/kotlin/ru/gildor/coroutines/retrofit/Result.kt
index 4298e8a..770f410 100644
--- a/src/main/kotlin/ru/gildor/coroutines/retrofit/Result.kt
+++ b/src/main/kotlin/ru/gildor/coroutines/retrofit/Result.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Andrey Mischenko
+ *
+ * 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 ru.gildor.coroutines.retrofit
import okhttp3.Response
@@ -12,8 +28,8 @@ public sealed class Result {
* Successful result of request without errors
*/
public class Ok(
- public val value: T,
- override val response: Response
+ public val value: T,
+ override val response: Response
) : Result(), ResponseResult {
override fun toString() = "Result.Ok{value=$value, response=$response}"
}
@@ -22,8 +38,8 @@ public sealed class Result {
* HTTP error
*/
public class Error(
- override val exception: HttpException,
- override val response: Response
+ override val exception: HttpException,
+ override val response: Response
) : Result(), ErrorResult, ResponseResult {
override fun toString() = "Result.Error{exception=$exception}"
}
@@ -33,7 +49,7 @@ public sealed class Result {
* exception occurred creating the request or processing the response
*/
public class Exception(
- override val exception: Throwable
+ override val exception: Throwable
) : Result(), ErrorResult {
override fun toString() = "Result.Exception{$exception}"
}
@@ -57,14 +73,12 @@ public interface ErrorResult {
/**
* Returns [Result.Ok.value] or `null`
*/
-public fun Result.getOrNull(): T? =
- if (this is Result.Ok) this.value else null
+public fun Result.getOrNull(): T? = (this as? Result.Ok)?.value
/**
* Returns [Result.Ok.value] or [default]
*/
-public fun Result.getOrDefault(default: T): T =
- getOrNull() ?: default
+public fun Result.getOrDefault(default: T): T = getOrNull() ?: default
/**
* Returns [Result.Ok.value] or throw [throwable] or [ErrorResult.exception]
diff --git a/src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt b/src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt
index d78a527..ba0015b 100644
--- a/src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt
+++ b/src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt
@@ -1,10 +1,31 @@
+/*
+ * Copyright 2018 Andrey Mischenko
+ *
+ * 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 ru.gildor.coroutines.retrofit
import kotlinx.coroutines.experimental.CoroutineScope
import kotlinx.coroutines.experimental.Unconfined
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.runBlocking
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertSame
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
import org.junit.Test
import retrofit2.Call
import retrofit2.HttpException
@@ -232,12 +253,12 @@ class CallAwaitTest {
}
private fun checkRequestCancelWithException(
- block: suspend (Call) -> T
+ block: suspend (Call) -> T
) = testBlocking {
val request = MockedCall(
- ok = DONE,
- autoStart = false,
- cancelException = IllegalStateException()
+ ok = DONE,
+ autoStart = false,
+ cancelException = IllegalStateException()
)
val async = async(coroutineContext, block = { block(request) })
//We shouldn't crash on cancel exception
@@ -252,8 +273,8 @@ class CallAwaitTest {
private fun checkJobCancelWithException(block: suspend (Call) -> T) = testBlocking {
val request = MockedCall(
- exception = IllegalArgumentException(),
- autoStart = false
+ exception = IllegalArgumentException(),
+ autoStart = false
)
val result = async(coroutineContext) {
block(request)
@@ -264,7 +285,7 @@ class CallAwaitTest {
}
private fun checkJobCancel(
- block: suspend (Call) -> T
+ block: suspend (Call) -> T
) = testBlocking {
val request = MockedCall(DONE, autoStart = false)
val async = async(coroutineContext) { block(request) }
@@ -277,3 +298,4 @@ class CallAwaitTest {
private fun testBlocking(block: suspend CoroutineScope.() -> Unit) {
runBlocking(Unconfined, block)
}
+
diff --git a/src/test/kotlin/ru/gildor/coroutines/retrofit/ResultTest.kt b/src/test/kotlin/ru/gildor/coroutines/retrofit/ResultTest.kt
index efc74ea..cb49699 100644
--- a/src/test/kotlin/ru/gildor/coroutines/retrofit/ResultTest.kt
+++ b/src/test/kotlin/ru/gildor/coroutines/retrofit/ResultTest.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Andrey Mischenko
+ *
+ * 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 ru.gildor.coroutines.retrofit
import org.junit.Assert.assertEquals
@@ -55,24 +71,24 @@ class ResultTest {
@Test
fun okToString() {
assertEquals(
- "Result.Ok{value=result, response=Response{protocol=http/1.1, code=200, message=mock response, url=http://localhost/}}",
- ok.toString()
+ "Result.Ok{value=result, response=Response{protocol=http/1.1, code=200, message=mock response, url=http://localhost/}}",
+ ok.toString()
)
}
@Test
fun errorToString() {
assertEquals(
- "Result.Error{exception=retrofit2.HttpException: HTTP 400 Response.error()}",
- error.toString()
+ "Result.Error{exception=retrofit2.HttpException: HTTP 400 Response.error()}",
+ error.toString()
)
}
@Test
fun exceptionToString() {
assertEquals(
- "Result.Exception{java.lang.IllegalArgumentException: Exception message}",
- exception.toString()
+ "Result.Exception{java.lang.IllegalArgumentException: Exception message}",
+ exception.toString()
)
}
}
\ No newline at end of file
diff --git a/src/test/kotlin/ru/gildor/coroutines/retrofit/util/MockedCall.kt b/src/test/kotlin/ru/gildor/coroutines/retrofit/util/MockedCall.kt
index b5e4286..c456412 100644
--- a/src/test/kotlin/ru/gildor/coroutines/retrofit/util/MockedCall.kt
+++ b/src/test/kotlin/ru/gildor/coroutines/retrofit/util/MockedCall.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Andrey Mischenko
+ *
+ * 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 ru.gildor.coroutines.retrofit.util
import okhttp3.MediaType
@@ -10,11 +26,11 @@ import retrofit2.HttpException
import retrofit2.Response
class MockedCall(
- private val ok: T? = null,
- private val error: HttpException? = null,
- private val exception: Throwable? = null,
- private val autoStart: Boolean = true,
- private val cancelException: Throwable? = null
+ private val ok: T? = null,
+ private val error: HttpException? = null,
+ private val exception: Throwable? = null,
+ private val autoStart: Boolean = true,
+ private val cancelException: Throwable? = null
) : Call {
private var executed: Boolean = false
private var cancelled: Boolean = false
@@ -62,12 +78,16 @@ class MockedCall(
}
-fun errorResponse(code: Int = 400, message: String = "Error response $code"): Response =
- Response.error(code, ResponseBody.create(MediaType.parse("text/plain"), message))
+fun errorResponse(
+ code: Int = 400,
+ message: String = "Error response $code"
+): Response {
+ return Response.error(code, ResponseBody.create(MediaType.parse("text/plain"), message))
+}
fun okHttpResponse(code: Int = 200): okhttp3.Response = okhttp3.Response.Builder()
- .code(code)
- .protocol(Protocol.HTTP_1_1)
- .message("mock response")
- .request(Request.Builder().url("http://localhost").build())
- .build()
\ No newline at end of file
+ .code(code)
+ .protocol(Protocol.HTTP_1_1)
+ .message("mock response")
+ .request(Request.Builder().url("http://localhost").build())
+ .build()
\ No newline at end of file
diff --git a/src/test/kotlin/ru/gildor/coroutines/retrofit/util/NullBodyCall.kt b/src/test/kotlin/ru/gildor/coroutines/retrofit/util/NullBodyCall.kt
index 97b1828..10ea485 100644
--- a/src/test/kotlin/ru/gildor/coroutines/retrofit/util/NullBodyCall.kt
+++ b/src/test/kotlin/ru/gildor/coroutines/retrofit/util/NullBodyCall.kt
@@ -1,11 +1,11 @@
/*
- * Copyright 2016-2017 JetBrains s.r.o.
+ * Copyright 2018 Andrey Mischenko
*
* 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
+ * 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,