aboutsummaryrefslogtreecommitdiff
path: root/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala
blob: 6292ecdd70c8af62b84ffb808edca086a7ff0c9c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.softwaremill.sttp

import java.nio.file.{Files, Paths}
import java.{io, util}

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer
import org.scalatest.concurrent.{PatienceConfiguration, ScalaFutures}
import org.scalatest.exceptions.TestFailedException
import org.scalatest.matchers.{MatchResult, Matcher}
import org.scalatest.{BeforeAndAfterAll, Suite}

import scala.concurrent.Future
import scala.concurrent.duration._
import scala.language.higherKinds
import scalaz._

trait TestHttpServer extends BeforeAndAfterAll with ScalaFutures with TestingPatience {
  this: Suite =>
  protected implicit val actorSystem: ActorSystem = ActorSystem("sttp-test")
  import actorSystem.dispatcher

  protected implicit val materializer = ActorMaterializer()
  protected val endpoint = uri"http://localhost:$port"

  override protected def beforeAll(): Unit = {
    Http().bindAndHandle(serverRoutes, "localhost", port).futureValue
  }

  override protected def afterAll(): Unit = {
    actorSystem.terminate().futureValue
  }

  def serverRoutes: Route
  def port: Int
}

trait ForceWrappedValue[R[_]] {
  def force[T](wrapped: R[T]): T
}

object ForceWrappedValue extends ScalaFutures with TestingPatience {

  val id = new ForceWrappedValue[Id] {
    override def force[T](wrapped: Id[T]): T =
      wrapped
  }
  val future = new ForceWrappedValue[Future] {

    override def force[T](wrapped: Future[T]): T =
      try {
        wrapped.futureValue
      } catch {
        case e: TestFailedException if e.getCause != null => throw e.getCause
      }
  }
  val scalazTask = new ForceWrappedValue[scalaz.concurrent.Task] {
    override def force[T](wrapped: scalaz.concurrent.Task[T]): T =
      wrapped.unsafePerformSyncAttempt match {
        case -\/(error) => throw error
        case \/-(value) => value
      }
  }
  val monixTask = new ForceWrappedValue[monix.eval.Task] {
    import monix.execution.Scheduler.Implicits.global

    override def force[T](wrapped: monix.eval.Task[T]): T =
      try {
        wrapped.runAsync.futureValue
      } catch {
        case e: TestFailedException => throw e.getCause
      }
  }
  val catsIo = new ForceWrappedValue[cats.effect.IO] {
    override def force[T](wrapped: cats.effect.IO[T]): T =
      wrapped.unsafeRunSync
  }
}

trait ForceWrapped extends ScalaFutures with TestingPatience { this: Suite =>
  type ForceWrappedValue[R[_]] = com.softwaremill.sttp.ForceWrappedValue[R]
  val ForceWrappedValue: com.softwaremill.sttp.ForceWrappedValue.type =
    com.softwaremill.sttp.ForceWrappedValue

  implicit class ForceDecorator[R[_], T](wrapped: R[T]) {
    def force()(implicit fwv: ForceWrappedValue[R]): T = fwv.force(wrapped)
  }
}

object EvalScala {
  import scala.tools.reflect.ToolBox

  def apply(code: String): Any = {
    val m = scala.reflect.runtime.currentMirror
    val tb = m.mkToolBox()
    tb.eval(tb.parse(code))
  }
}

object CustomMatchers {
  class FileContentsMatch(file: java.io.File) extends Matcher[java.io.File] {
    override def apply(left: io.File): MatchResult = {
      val inBA = Files.readAllBytes(Paths.get(left.getAbsolutePath))
      val expectedBA = Files.readAllBytes(Paths.get(file.getAbsolutePath))
      MatchResult(
        util.Arrays.equals(inBA, expectedBA),
        "The files' contents are not the same",
        "The files' contents are the same"
      )
    }
  }

  def haveSameContentAs(file: io.File) = new FileContentsMatch(file)
}

trait TestingPatience extends PatienceConfiguration {
  override implicit val patienceConfig: PatienceConfig =
    PatienceConfig(timeout = 5.seconds, interval = 150.milliseconds)
}