Skip to content
This repository has been archived by the owner on Jan 7, 2020. It is now read-only.

Commit

Permalink
Testing user interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
chepiov committed May 2, 2019
1 parent b597f2a commit 296fc41
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/org/chepiov/tomodoro/actors/UserActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ case object UserActor {
): Props =
Props(new UserActor(chatId, chat, timeUnit, defaultSettings, snapshotInterval))

final case class CommandMsg(cmd: Command, ask: () => Unit)
final case class CommandMsg(cmd: Command, ack: () => Unit)

final case class QueryMsg(query: UserInfoQuery, ask: () => Unit)
final case class QueryMsg(query: UserInfoQuery, ack: () => Unit)

final case class MessageSentEvent(message: TSendMessage)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package org.chepiov.tomodoro.interpreters

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import cats.Id
import cats.effect.{ContextShift, IO}
import cats.syntax.flatMap._
import com.typesafe.config.ConfigFactory
import io.chrisdavenport.log4cats.Logger
import io.chrisdavenport.log4cats.slf4j.Slf4jLogger
import org.chepiov.tomodoro.actors.UserActor.{CommandMsg, QueryMsg}
import org.chepiov.tomodoro.algebras.User.{Continue, GetState}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._

//noinspection AppropriateActorConstructorNotFound
@SuppressWarnings(
Array(
"org.wartremover.warts.NonUnitStatements",
"org.wartremover.warts.Product",
"org.wartremover.warts.Serializable"
)
)
class UserInterpreterSpec
extends TestKit(ActorSystem("test-system", ConfigFactory.load("application-persistence-test"))) with WordSpecLike
with Matchers with BeforeAndAfterAll with ImplicitSender {
import UserInterpreterSpec._

override def afterAll: Unit = {
TestKit.shutdownActorSystem(system)
}

val userActor: ActorRef = system.actorOf(Props(classOf[SuccessUserActor], testActor))
val badUserActor: ActorRef = system.actorOf(Props[FailureUserActor])

implicit val cs: ContextShift[IO] = IO.contextShift(ExecutionContext.global)

implicit def logger: Logger[IO] = Slf4jLogger.getLogger[IO]

"User" should {
"deliver actions to actor" in {
val program: IO[Unit] = for {
user <- UserInterpreter[Id, IO](1L, userActor)
_ <- user.advance(Continue(0))
_ <- user.info(GetState)
} yield {
expectMsgAllOf(Continue(0), GetState)
()
}
program.unsafeRunSync()
}
}

it should {
"handle errors" in {
val program: IO[Unit] = for {
user <- UserInterpreter[Id, IO](1L, badUserActor)
advance <- IO.race(user.advance(Continue(0)), IO.timer(ExecutionContext.global).sleep(3.seconds))
query <- IO.race(user.info(GetState), IO.timer(ExecutionContext.global).sleep(3.seconds))
} yield {
advance.isRight shouldBe true
query.isRight shouldBe true
()
}
program.unsafeRunSync()
}
}
}

@SuppressWarnings(Array("org.wartremover.warts.Any", "org.wartremover.warts.Throw"))
case object UserInterpreterSpec {
class SuccessUserActor(probe: ActorRef) extends Actor {
override def receive: Receive = {
case CommandMsg(cmd, ack) =>
probe ! cmd
ack()
case QueryMsg(query, ack) =>
probe ! query
ack()
}
}

class FailureUserActor extends Actor {
override def receive: Receive = {
case CommandMsg(_, _) => throw new RuntimeException()
case QueryMsg(_, _) => throw new RuntimeException()
}
}
}

0 comments on commit 296fc41

Please sign in to comment.