Bohtvaroh

scalacheck generators

Sep 30th, 2013
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 3.10 KB | None | 0 0
  1. import org.joda.time.DateTime
  2.  
  3. import org.scalacheck.{Arbitrary, Gen}
  4. import org.scalacheck.Gen.oneOf
  5.  
  6. import scalaz._
  7. import Scalaz._
  8.  
  9. trait ProjectDateGenerator {
  10.   case class Year(q: String, a: Option[Int])
  11.   case class Month(q: String, a: Option[Int])
  12.   case class Date(q: String, year: Year, month: Month)
  13.  
  14.   val dateGen: Gen[Date] = for {
  15.     year  <- oneOf(emptyYearGen, yearGen)
  16.     month <- oneOf(emptyMonthGen, alphaMonthGen, numericMonthGen)
  17.     input <- inputGen(year, month)
  18.   } yield Date(input, year, month)
  19.  
  20.   implicit val arbContexts = Arbitrary(dateGen)
  21.  
  22.   // privates
  23.  
  24.   private lazy val emptyYearGen: Gen[Year] = oneOfSeq(Year("", None))
  25.   private lazy val yearGen: Gen[Year] = oneOf((1950 to DateTime.now.getYear) map (y => Year(y.toString, Some(y))))
  26.  
  27.   private lazy val emptyMonthGen: Gen[Month] = oneOfSeq(Month("", None))
  28.   private lazy val alphaMonthGen: Gen[Month] = {
  29.     val variants = for {
  30.       (m, spellings) <- ResourceLoader.months()
  31.       spelling       <- spellings
  32.     } yield Month(spelling, Some(m))
  33.     oneOf(variants.toSeq)
  34.   }
  35.   private lazy val numericMonthGen: Gen[Month] = {
  36.     val variants = for {
  37.       m     <- 1 to 12
  38.       month <- Seq(Month(m.toString, Some(m)), Month(padZeros(m, 2), Some(m))) // gen both "1" and "01"
  39.     } yield month
  40.     oneOf(variants)
  41.   }
  42.  
  43.   private def inputGen(year: Year, month: Month): Gen[String] = {
  44.     val inputs = {
  45.       def join(s1: String, w: String, s2: String): String =
  46.         if (s1.isEmpty) s2
  47.         else if (s2.isEmpty) s1
  48.         else s1 + w + s2
  49.  
  50.       import scala.language.implicitConversions
  51.       implicit def yearToString(y: Year): String = if (y.a.isDefined) y.q else ""
  52.       implicit def monthToString(m: Month): String = if (m.a.isDefined) m.q else ""
  53.  
  54.       List(
  55.         join(month, " ", year),  // september 2010, sep 2010, 09 2010
  56.         join(year,  " ", month), // 2010 september, 2010 sep, 2010 09
  57.         join(month, ".", year),  // september.2010, sep.2010, 09.2010
  58.         join(year,  ".", month), // 2010.september, 2010.sep, 2010.09
  59.         join(year,  "",  month), // 2010september,  2010sep,  201009
  60.         join(month, "",  year)   // september2010,  sep2010,  092010
  61.       )
  62.     }
  63.  
  64.     def addNoise(inputs: List[String]): List[String] =
  65.       inputs <*> List(identity, "from " + _, "since " + _, "to " + _, "till " + _)
  66.  
  67.     oneOfSeq(addNoise(inputs): _*)
  68.   }
  69.  
  70.   private def oneOfSeq[T](xs: T*) = oneOf(xs)
  71.   private def padZeros(i: Int, width: Int): String = { val spec = s"%0${width}d"; spec.format(i) }
  72. }
  73.  
  74. ----------------------------------------------------------------------------------------------
  75.  
  76. import org.scalatest.FunSuite
  77. import org.scalatest.prop.Checkers
  78. import org.scalacheck.Prop.forAll
  79.  
  80. class ProjectDateParserSpec extends FunSuite
  81. with Checkers
  82. with Generators
  83. with ParseFunctions {
  84.  
  85.   test("project dates parser") { check(forAll { satisfies _ }) }
  86.  
  87.   private def satisfies(date: Date) = {
  88.     val result = parseDate(date.q)
  89.     val year = result.year
  90.     val month = result.month
  91.  
  92.     year == date.year.a && month == date.month.a
  93.   }
  94. }
Advertisement
Add Comment
Please, Sign In to add comment