diff options
author | adamw <adam@warski.org> | 2017-11-13 15:39:31 +0100 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-11-13 15:39:31 +0100 |
commit | d7d26fbda8559adad2737c2df73076f002c194f9 (patch) | |
tree | 04ff4bfa0b9d0806c32f20033f6c8536cf47a260 /core | |
parent | a0fdfa6f6114aec289e46c4261522244b160e522 (diff) | |
download | sttp-d7d26fbda8559adad2737c2df73076f002c194f9.tar.gz sttp-d7d26fbda8559adad2737c2df73076f002c194f9.tar.bz2 sttp-d7d26fbda8559adad2737c2df73076f002c194f9.zip |
#44: supporting type conversion in the backend stub
Diffstat (limited to 'core')
4 files changed, 96 insertions, 11 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala index f35bd40..083b1c3 100644 --- a/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala +++ b/core/src/main/scala/com/softwaremill/sttp/HttpURLConnectionBackend.scala @@ -241,11 +241,7 @@ class HttpURLConnectionBackend private ( asString(enc) case ResponseAsByteArray => - val os = new ByteArrayOutputStream - - transfer(is, os) - - os.toByteArray + toByteArray(is) case ResponseAsStream() => // only possible when the user requests the response as a stream of diff --git a/core/src/main/scala/com/softwaremill/sttp/package.scala b/core/src/main/scala/com/softwaremill/sttp/package.scala index ed685fa..b641a77 100644 --- a/core/src/main/scala/com/softwaremill/sttp/package.scala +++ b/core/src/main/scala/com/softwaremill/sttp/package.scala @@ -257,6 +257,12 @@ package object sttp { transfer() } + private[sttp] def toByteArray(is: InputStream): Array[Byte] = { + val os = new ByteArrayOutputStream + transfer(is, os) + os.toByteArray + } + private[sttp] def codeIsSuccess(c: Int): Boolean = c >= 200 && c < 300 private[sttp] def concatByteBuffers(bb1: ByteBuffer, diff --git a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala index 553afff..8a91e36 100644 --- a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala +++ b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala @@ -1,7 +1,9 @@ package com.softwaremill.sttp.testing +import java.io.{File, InputStream} + import com.softwaremill.sttp.testing.SttpBackendStub._ -import com.softwaremill.sttp.{MonadError, Request, Response, SttpBackend} +import com.softwaremill.sttp._ import scala.language.higherKinds import scala.util.{Failure, Success, Try} @@ -46,8 +48,9 @@ class SttpBackendStub[R[_], S] private (rm: MonadError[R], case matcher: Matcher[T @unchecked] if matcher(request) => Try(matcher.response(request).get) } match { - case Some(Success(response)) => wrapResponse(response) - case Some(Failure(e)) => rm.error(e) + case Some(Success(response)) => + wrapResponse(tryAdjustResponseType(request.response, response)) + case Some(Failure(e)) => rm.error(e) case None => fallback match { case None => wrapResponse(DefaultResponse) @@ -133,4 +136,44 @@ object SttpBackendStub { }) } } + + private[sttp] def tryAdjustResponseType[T, U](ra: ResponseAs[T, _], + r: Response[U]): Response[_] = { + r.body match { + case Left(_) => r + case Right(body) => + val newBody: Any = tryAdjustResponseBody(ra, body).getOrElse(body) + r.copy(body = Right(newBody)) + } + } + + private[sttp] def tryAdjustResponseBody[T, U](ra: ResponseAs[T, _], + b: U): Option[T] = { + ra match { + case IgnoreResponse => Some(()) + case ResponseAsString(enc) => + b match { + case s: String => Some(s) + case a: Array[Byte] => Some(new String(a, enc)) + case is: InputStream => Some(new String(toByteArray(is), enc)) + case _ => None + } + case ResponseAsByteArray => + b match { + case s: String => Some(s.getBytes(Utf8)) + case a: Array[Byte] => Some(a) + case is: InputStream => Some(toByteArray(is)) + case _ => None + } + case ras @ ResponseAsStream() => + None + case ResponseAsFile(file, overwrite) => + b match { + case f: File => Some(f) + case _ => None + } + case MappedResponseAs(raw, g) => + tryAdjustResponseBody(raw, b).map(g) + } + } } diff --git a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala index 292d324..7e6f15f 100644 --- a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala +++ b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala @@ -1,15 +1,15 @@ package com.softwaremill.sttp.testing +import java.io.ByteArrayInputStream import java.util.concurrent.TimeoutException import scala.concurrent.ExecutionContext.Implicits.global - import com.softwaremill.sttp._ import org.scalatest.concurrent.ScalaFutures import org.scalatest.{FlatSpec, Matchers} class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { - val testingStub = SttpBackendStub(HttpURLConnectionBackend()) + private val testingStub = SttpBackendStub(HttpURLConnectionBackend()) .whenRequestMatches(_.uri.path.startsWith(List("a", "b"))) .thenRespondOk() .whenRequestMatches(_.uri.paramsMap.get("p").contains("v")) @@ -93,7 +93,21 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { result.failed.futureValue shouldBe a[TimeoutException] } - val testingStubWithFallback = SttpBackendStub + it should "try to convert a basic response to a mapped one" in { + implicit val s = SttpBackendStub(HttpURLConnectionBackend()) + .whenRequestMatches(_ => true) + .thenRespond("10") + + val result = sttp + .get(uri"http://example.org") + .mapResponse(_.toInt) + .mapResponse(_ * 2) + .send() + + result.body should be(Right(20)) + } + + private val testingStubWithFallback = SttpBackendStub .withFallback(testingStub) .whenRequestMatches(_.uri.path.startsWith(List("c"))) .thenRespond("ok") @@ -111,4 +125,30 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures { val r = sttp.post(uri"http://example.org/a/b").send() r.is200 should be(true) } + + private val s = "Hello, world!" + private val adjustTestData = List[(Any, ResponseAs[_, _], Any)]( + (s, IgnoreResponse, Some(())), + (s, ResponseAsString(Utf8), Some(s)), + (s.getBytes(Utf8), ResponseAsString(Utf8), Some(s)), + (new ByteArrayInputStream(s.getBytes(Utf8)), + ResponseAsString(Utf8), + Some(s)), + (10, ResponseAsString(Utf8), None), + ("10", + MappedResponseAs(ResponseAsString(Utf8), (_: String).toInt), + Some(10)), + (10, MappedResponseAs(ResponseAsString(Utf8), (_: String).toInt), None) + ) + + behavior of "tryAdjustResponseBody" + + for { + (body, responseAs, expectedResult) <- adjustTestData + } { + it should s"adjust $body to $expectedResult when specified as $responseAs" in { + SttpBackendStub.tryAdjustResponseBody(responseAs, body) should be( + expectedResult) + } + } } |