aboutsummaryrefslogtreecommitdiff
path: root/tests/src/test/scala/com/softwaremill/sttp/testHelpers.scala
blob: 1a57b7e751b71f0d7f0a42a84152d58be2200a87 (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
122
123
124
125
126
127
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 scala.util.Try
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 scalaTry = new ForceWrappedValue[Try] {
    override def force[T](wrapped: Try[T]): T = wrapped.get
  }

  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 if e.getCause != null => 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)
}