Skip to content

Instantly share code, notes, and snippets.

@filippovitale
Created March 1, 2015 01:54
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 filippovitale/d3a46bb0189fff37ce73 to your computer and use it in GitHub Desktop.
Save filippovitale/d3a46bb0189fff37ce73 to your computer and use it in GitHub Desktop.
Examples.scala
import org.specs2._
import scalaz.syntax.id._
/**
* https://github.com/swlaschin/PropertyBasedTesting/blob/master/part2.fsx
*/
class Examples extends Specification with ScalaCheck {
def is = commutative ^ inverse ^ easyToVerify ^ invariant ^ structuralInduction ^ idempotent ^ oracle
/**
* "Different paths, same destination"
*/
val commutative =
"[+1 then sort] should be same as [sort then +1]" !
prop { (xs: List[BigInt]) => xs.map(_ + 1).sorted == xs.sorted.map(_ + 1)} ^
"[append minValue then sort] should be same as [sort then prepend minValue]" !
prop { (xs: List[Int]) => (xs :+ Int.MinValue).sorted == Int.MinValue +: xs.sorted} ^
"[negate then sort] should be same as [sort then negate then reverse]" !
prop { (xs: List[BigInt]) => xs.map(_ * -1).sorted == xs.sorted.map(_ * -1).reverse} ^
"[append any value then reverse] should be same as [reverse then prepend same value]" !
prop { (xs: List[AnyVal], x: AnyVal) => (xs :+ x).reverse == x +: xs.reverse} ^
end
/**
* "There and back again"
*/
val inverse =
"[reverse then reverse] should be same as [original]" !
prop { (xs: List[AnyVal]) => xs.reverse.reverse == xs} ^
end
/**
* "Hard to prove, easy to verify"
*/
val easyToVerify =
"[concatenating the elements of a string split by commas] should be same as [the original string]" !
prop { (s: String) => s.mkString(",").split(",").reduce(_ + _) == s} ^ // what about empty case? force it!
"adjacent pairs from a list should be ordered" !
prop { (xs: List[Int]) => xs.sorted.sliding(2).forall(t => t.head <= t.last)} ^
end
/**
* "Some things never change"
*/
val invariant =
"[a sorted list] should have same length as [original]" !
prop { (xs: List[Int]) => xs.sorted.length == xs.length} ^
"[a sorted list] should have the same contents as [the original list]" !
prop { (xs: List[Int]) => xs.sorted.toSet == xs.toSet} ^
"[a reversed list] should have same length as [original]" !
prop { (xs: List[Int]) => xs.reverse.length == xs.length} ^
end
/**
* "Solving a smaller problem"
*/
val structuralInduction =
"first element is <= than second, and tail is also sorted" !
prop { (xs: List[Int]) => xs.sorted.tails.takeWhile(_.size > 1).forall(l => l.head <= l(1))} ^
end
/**
* "The more things change, the more they stay the same"
*/
val idempotent =
"[sorting twice] should give the same result as [sorting once]" !
prop { (xs: List[Int]) => xs.sorted.sorted == xs.sorted} ^
end
/**
* "Test Oracle"
*/
val oracle =
"[quicksort] should give the same result as [sorted]" !
prop { (xs: List[Int]) => xs.sorted == (xs.toArray <| scala.util.Sorting.quickSort).toList} ^
end
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment