Skip to content

Instantly share code, notes, and snippets.

@debasishg
Created October 10, 2014 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save debasishg/f14fd21a8ef14a35e65e to your computer and use it in GitHub Desktop.
Save debasishg/f14fd21a8ef14a35e65e to your computer and use it in GitHub Desktop.
generator and property for ADTs with custom initialization logic
// the ADT
sealed trait Account {
def no: String
def name: String
def openingDate: Date
def closeDate: Option[Date]
}
final case class CheckingAccount private[prop](no: String, name: String, openingDate: Date, closeDate: Option[Date])
extends Account
// the smart constructor containing initialization logic
object Account {
private val validDate: (Date, Date) => Boolean = { (d1, d2) => d1 before d2 }
def checkingAccount(no: String, name: String, openingDate: Date,
closeDate: Option[Date] = None): Try[Account] = {
if (closeDate.map(validDate(_, openingDate)).getOrElse(false))
Failure(new IllegalArgumentException(
s"Account close date [$closeDate] cannot be earlier than opening date [$openingDate]"))
else Success(CheckingAccount(no, name, openingDate, closeDate))
}
}
// generator
implicit val arbTAccount: Arbitrary[Try[Account]] = Arbitrary {
for {
no <- Gen.oneOf("1", "2", "3")
nm <- Gen.oneOf("john", "david", "mary")
od <- arbitrary[Date]
} yield checkingAccount(no, nm, od)
}
// property
property("account open date < close date if close date is present") = forAll((a: Try[Account]) =>
a match {
case Success(acc) => acc.closeDate.map(cd => (acc.openingDate before cd) == true).getOrElse(true)
case Failure(ex) => false == false
}
)
@missingfaktor
Copy link

The before logic is duplicated in both smart constructor and property, isn't it?

@debasishg
Copy link
Author

But that's the property you r proving. Hence you need to verify the same from the generated data. Instead of using acc.openingDate before cd you could use the validDate function also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment