Skip to content

Instantly share code, notes, and snippets.

@miguel-vila
Last active December 27, 2015 13:09
Show Gist options
  • Save miguel-vila/7330675 to your computer and use it in GitHub Desktop.
Save miguel-vila/7330675 to your computer and use it in GitHub Desktop.
import org.scalacheck.{ Properties , Arbitrary , Gen }
import org.scalacheck.Prop.forAll
import play.api.libs.json._
case class Subdocument(m: String, n: Int, list: List[Int], days: Set[WeekDay.Value])
case class Document(id: String, n: Int, subDoc: Subdocument)
object WeekDay extends Enumeration {
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
object EnumFormat{
def apply[E <: Enumeration](enum: E) = new Format[E#Value]{
def reads(json: JsValue): JsResult[E#Value] = json match {
case JsString(s) => {
try {
JsSuccess(enum.withName(s))
} catch {
case _: NoSuchElementException => JsError(s"Enumeration expected of type: '${enum.getClass}', but it does not appear to contain the value: '$s'")
}
}
case _ => JsError("String value expected")
}
def writes(e: E#Value): JsValue = JsString(e.toString())
}
}
object Formats {
implicit val weekdayFormat = EnumFormat(WeekDay)
implicit val subdocFormat = Json.format[Subdocument]
implicit val docFormat = Json.format[Document]
}
object ArbitraryDocs{
implicit def arbitraryWeekday = Arbitrary(Gen.oneOf(WeekDay.values.toSeq))
def arbitrarySubdoc = Arbitrary{
for(
m <- Arbitrary.arbString.arbitrary;
n <- Arbitrary.arbInt.arbitrary;
l <- Arbitrary.arbitrary[List[Int]];
w <- Arbitrary.arbitrary[Set[WeekDay.Value]]
) yield Json.obj("m" -> m,"n"->n,"list"->l,"days"->w.map(_.toString()))
}
implicit def arbitraryDoc = Arbitrary{
for(
id <- Arbitrary.arbString.arbitrary;
n <- Arbitrary.arbInt.arbitrary;
subdoc <- arbitrarySubdoc.arbitrary
) yield Json.obj("id"->id,"n"->n,"subDoc"->subdoc)
}
implicit def arbitrarySubdocObj = Arbitrary{
for(
m <- Arbitrary.arbString.arbitrary;
n <- Arbitrary.arbInt.arbitrary;
l <- Arbitrary.arbitrary[List[Int]];
w <- Arbitrary.arbitrary[Set[WeekDay.Value]]
) yield Subdocument(m,n,l,w)
}
implicit def arbitraryDocObj = Arbitrary{
for(
id <- Arbitrary.arbString.arbitrary;
n <- Arbitrary.arbInt.arbitrary;
subdoc <- arbitrarySubdocObj.arbitrary
) yield Document(id,n,subdoc)
}
}
object FormatSpec extends Properties("formats"){
import Formats.docFormat
import ArbitraryDocs._
property("writes is the inverse of reads") = forAll { (a: Document) =>
docFormat.reads(docFormat.writes(a)) match{
case JsSuccess(b,_) => a==b
case _ => false
}
}
property("reads is the inverse of writes") = forAll { (a: JsObject) =>
docFormat.reads(a) match {
case JsSuccess(b,_) => docFormat.writes(b) == a
case _ => false
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment