Rewrite GameRepo tests using IO

pull/1/merge
Thibault Duplessis 2012-03-08 12:39:04 +01:00
parent 920304c5e5
commit 8dde4beb28
3 changed files with 103 additions and 17 deletions

View File

@ -8,6 +8,7 @@ package object system
extends OrnicarValidation
with OrnicarCommon
//with OrnicarNonEmptyLists
with scalaz.NonEmptyLists
with scalaz.Strings
with scalaz.Booleans {

View File

@ -1,22 +1,29 @@
package lila.system
import lila.chess._
import scalaz.{ Success, Failure }
import scalaz.effects._
import com.mongodb.casbah.Imports._
class GameRepoTest extends SystemTest {
val env = SystemEnv()
val repo = env.gameRepo
val anyGame = repo.anyGame.get
val anyGame = repo.findOne(DBObject()) flatMap repo.decode get // unsafe but who cares
"the game repo" should {
"find a game" in {
"by ID" in {
"non existing" in {
repo game "haha" must beNone
repo game "haha" must beIO.like {
case g g must beFailure
}
}
"existing" in {
repo game anyGame.id must beSome.like {
case g g.id must_== anyGame.id
repo game anyGame.id must beIO.like {
case vg vg must beSuccess.like {
case g g.id must_== anyGame.id
}
}
}
}
@ -24,43 +31,63 @@ class GameRepoTest extends SystemTest {
"find a player" in {
"by private ID" in {
"non existing" in {
repo player "huhu" must be none
repo player "huhu" must beIO.like {
case p p must beFailure
}
}
"existing" in {
val player = anyGame.players.head
anyGame fullIdOf player flatMap repo.player must beSome.like {
case (g, p) p.id must_== player.id
anyGame fullIdOf player map repo.player must beSome.like {
case iop iop must beIO.like {
case vgp vgp must beSuccess.like {
case (g, p) p.id must_== player.id
}
}
}
}
}
"by ID and color" in {
"non existing" in {
repo.player("haha", White) must beNone
repo.player("haha", White) must beIO.like {
case vp vp must beFailure
}
}
"existing" in {
val player = anyGame.players.head
repo.player(anyGame.id, player.color) must beSome.like {
case (g, p) p.id must_== player.id
repo.player(anyGame.id, player.color) must beIO.like {
case vgp vgp must beSuccess.like {
case (g, p) p.id must_== player.id
}
}
}
}
}
"insert a new game" in {
sequential
val game = newDbGameWithRandomIds()
repo insert game
"find the saved game" in {
repo game game.id must_== Some(game)
(for {
_ repo insert game
newGame repo game game.id
} yield newGame) must beIO.like {
case iog iog must beSuccess.like {
case g g must_== game
}
}
}
}
"update a game" in {
sequential
val game = newDbGameWithRandomIds()
repo insert game
val updated = game.copy(turns = game.turns + 1)
repo save updated
"find the updated game" in {
repo game updated.id must_== Some(updated)
(for {
_ repo insert game
_ repo save updated
newGame repo game game.id
} yield newGame) must beIO.like {
case iog iog must beSuccess.like {
case g g must_== updated
}
}
}
}
}

View File

@ -12,6 +12,64 @@ trait SystemTest
with OrnicarValidationMatchers
with Fixtures {
import util.control.Exception.allCatch
import org.specs2.execute.{ Failure, Success, Result }
import org.specs2.matcher._
import scalaz.effects._
/** matcher for an IO */
def beIO[A](t: A) = new Matcher[IO[A]] {
def apply[S <: IO[A]](value: Expectable[S]) = {
val expected = t
(allCatch either { value.value.unsafePerformIO }).fold(
e result(false,
"IO fails with " + e,
"IO fails with " + e,
value),
a result(a == expected,
a + " is IO with value " + expected,
a + " is not IO with value " + expected,
value)
)
}
}
def beIO[A] = new Matcher[IO[A]] {
def apply[S <: IO[A]](value: Expectable[S]) = {
val performed = allCatch either { value.value.unsafePerformIO }
result(performed.isRight,
"IO perfoms successfully",
"IO fails",
value)
}
def like(f: PartialFunction[A, MatchResult[_]]) = this and partialMatcher(f)
private def partialMatcher(
f: PartialFunction[A, MatchResult[_]]) = new Matcher[IO[A]] {
def apply[S <: IO[A]](value: Expectable[S]) = {
(allCatch either { value.value.unsafePerformIO }).fold(
e result(false,
"IO fails with " + e,
"IO fails with " + e,
value),
a {
val res: Result = a match {
case t if f.isDefinedAt(t) f(t).toResult
case _ Failure("function undefined")
}
result(res.isSuccess,
a + " is IO[A] and " + res.message,
a + " is not IO[A] with value " + res.message,
value)
}
)
}
}
}
implicit def stringToBoard(str: String): Board = Visual << str
implicit def richDbGame(dbGame: DbGame) = new {