From 4b6a0a999e935a94501da272a12956c024141cb2 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Mon, 11 Nov 2013 14:20:16 +0100 Subject: SI-7443 Use typeclass instance for {Range,NumericRange}.sum Previously both Range and NumeriRange used formula for sum of elements of arithmetic series and thus always assumed that provided Numeric is regular one. Bug is now fixed by conservatively checking if Numeric is one of default ones and the formula still holds. --- test/files/scalacheck/range.scala | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'test') diff --git a/test/files/scalacheck/range.scala b/test/files/scalacheck/range.scala index 6c7c32bfdf..1eb186f303 100644 --- a/test/files/scalacheck/range.scala +++ b/test/files/scalacheck/range.scala @@ -127,6 +127,47 @@ abstract class RangeTest(kind: String) extends Properties("Range "+kind) { (visited == expectedSize(r)) :| str(r) } + property("sum") = forAll(myGen) { r => +// println("----------") +// println("sum "+str(r)) + val rSum = r.sum + val expected = r.length match { + case 0 => 0 + case 1 => r.head + case _ => ((r.head + r.last).toLong * r.length / 2).toInt + } +// println("size: " + r.length) +// println("expected: " + expected) +// println("obtained: " + rSum) + + (rSum == expected) :| str(r) + } + +/* checks that sum respects custom Numeric */ + property("sumCustomNumeric") = forAll(myGen) { r => + val mod = 65536 + object mynum extends Numeric[Int] { + def plus(x: Int, y: Int): Int = (x + y) % mod + override def zero = 0 + + def fromInt(x: Int): Int = ??? + def minus(x: Int, y: Int): Int = ??? + def negate(x: Int): Int = ??? + def times(x: Int, y: Int): Int = ??? + def toDouble(x: Int): Double = ??? + def toFloat(x: Int): Float = ??? + def toInt(x: Int): Int = ((x % mod) + mod * 2) % mod + def toLong(x: Int): Long = ??? + def compare(x: Int, y: Int): Int = ??? + } + + val rSum = r.sum(mynum) + val expected = mynum.toInt(r.sum) + + (rSum == expected) :| str(r) + } + + property("length") = forAll(myGen suchThat (r => expectedSize(r).toInt == expectedSize(r))) { r => // println("length "+str(r)) (r.length == expectedSize(r)) :| str(r) -- cgit v1.2.3