This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object FixturesTest extends DefaultRunnableSpec with DomainFixtures { | |
def spec: ZSpec[TestEnvironment, Failure] = | |
suite("Fixtures test")( | |
testM("positiveIntGen generates positive ints") { | |
check(positiveIntGen) { positiveInt => | |
assert(positiveInt > 0)(isTrue) | |
} | |
}, | |
testM("nonemptyStringGen generates nonempty strings") { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object UserTest extends DefaultRunnableSpec with DomainFixtures { | |
def spec: ZSpec[TestEnvironment, Failure] = | |
suite("UserTest")( | |
testM("creating a user with valid input should succeed") { | |
check(positiveIntGen, nonemptyStringGen) { (positiveInt, nonemptyString) => | |
val user = User.build(positiveInt, nonemptyString) | |
assert(user)(isRight) | |
} | |
}, | |
testM("creating a user with id=0 should fail") { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object UserService { | |
def getUser(id: Int): ZIO[UserPersistence, AppError, User] = RIO.accessM(_.get.get(id)) | |
def createUser(id: Int, name: String): ZIO[UserPersistence, AppError, User] = | |
for { | |
user <- ZIO.fromEither(User.build(id, name)) | |
stored <- RIO.accessM[UserPersistence](_.get.create(user)) | |
} yield stored | |
def deleteUser(id: Int): RIO[UserPersistence, Boolean] = RIO.accessM(_.get.delete(id)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class TestDB(users: Ref[Vector[User]]) extends StoragePort { | |
def get(id: Int): IO[AppError, User] = | |
users.get.flatMap(users => IO.require(UserNotFound(id))(Task.succeed(users.find(_.id.value == id)))) | |
def create(user: User): IO[AppError, User] = | |
users.update(_ :+ user).map(_ => user) | |
def delete(id: Int): Task[Boolean] = | |
users.modify(users => true -> users.filterNot(_.id.value == id)) | |
} | |
object TestDB { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object UserServiceTest extends DefaultRunnableSpec with DomainFixtures { | |
def spec: ZSpec[TestEnvironment, Failure] = | |
suite("UserService unit test")( | |
testM("get a non existing user should fail") { | |
assertM(getUser(100).run)(fails(anything)) | |
}, | |
testM("create a user then get it should return the same user ") { | |
checkM(userGen) { user => |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val DoobieVersion = "0.12.1" | |
libraryDependencies ++= Seq( | |
"org.tpolecat" %% "doobie-core" % DoobieVersion, | |
"org.tpolecat" %% "doobie-h2" % DoobieVersion, | |
//needed for functional stuff | |
"dev.zio" %% "zio-interop-cats" % "2.0.0.0-RC12" | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zio.experiment.domain.model.AppError | |
import zio.experiment.domain.model.User.{ User => UserDomain } | |
case class User(id: Int, name: String) | |
object User { | |
implicit class UserConversions(user: User) { | |
def toDomainUser: Either[AppError, UserDomain] = | |
UserDomain.build(user.id, user.name) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zio.experiment.domain.model.AppError | |
import zio.experiment.domain.model.User.{ User => UserDomain } | |
case class User(id: Int, name: String) | |
object User { | |
implicit class UserConversions(user: User) { | |
def toDomainUser: Either[AppError, UserDomain] = | |
UserDomain.build(user.id, user.name) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zio.experiment.adapter.model.{User => UserStored} | |
object SQL { | |
def get(id: Int): Query0[UserStored] = | |
sql"""SELECT * FROM USERS WHERE ID = $id """.query[UserStored] | |
def create(user: UserStored): Update0 = | |
sql"""INSERT INTO USERS (id, name) VALUES (${user.id}, ${user.name})""".update | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import doobie.h2.H2Transactor | |
import scala.concurrent.ExecutionContext | |
import zio.Task | |
import zio.interop.catz._ | |
object DoobiePersistenceService { | |
def mkTransactor( | |
conf: DbConfig, | |
connectEC: ExecutionContext, |