diff options
author | Josh Suereth <Joshua.Suereth@gmail.com> | 2012-09-20 10:22:01 -0700 |
---|---|---|
committer | Josh Suereth <Joshua.Suereth@gmail.com> | 2012-09-20 10:22:01 -0700 |
commit | 45c0b2428219b6a00514e21529650b32631880b6 (patch) | |
tree | 88eeb6ce02a1ec9dda21e77f7add4a995a8b9879 /test/files/scalacheck | |
parent | 1fc89420688d2123615e89a15e515c801729be5a (diff) | |
parent | 05367235ef4c519521cb28073f951e3d55fe3aad (diff) | |
download | scala-45c0b2428219b6a00514e21529650b32631880b6.tar.gz scala-45c0b2428219b6a00514e21529650b32631880b6.tar.bz2 scala-45c0b2428219b6a00514e21529650b32631880b6.zip |
Merge pull request #1339 from rkuhn/wip-6389-finite-duration-mult
enable integer multiplication/divison on FiniteDuration, see SI-6389
Diffstat (limited to 'test/files/scalacheck')
-rw-r--r-- | test/files/scalacheck/duration.scala | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/test/files/scalacheck/duration.scala b/test/files/scalacheck/duration.scala new file mode 100644 index 0000000000..5e93638614 --- /dev/null +++ b/test/files/scalacheck/duration.scala @@ -0,0 +1,69 @@ +import org.scalacheck._ +import Prop._ +import Gen._ +import Arbitrary._ +import math._ +import concurrent.duration.Duration.fromNanos + +object Test extends Properties("Division of Duration by Long") { + + val weightedLong = + frequency( + 1 -> choose(-128L, 127L), + 1 -> (arbitrary[Byte] map (_.toLong << 8)), + 1 -> (arbitrary[Byte] map (_.toLong << 16)), + 1 -> (arbitrary[Byte] map (_.toLong << 24)), + 1 -> (arbitrary[Byte] map (_.toLong << 32)), + 1 -> (arbitrary[Byte] map (_.toLong << 40)), + 1 -> (arbitrary[Byte] map (_.toLong << 48)), + 1 -> (choose(-127L, 127L) map (_ << 56)) + ) + + val genTwoSmall = for { + a <- weightedLong + b <- choose(-(Long.MaxValue / max(1, abs(a))), Long.MaxValue / max(1, abs(a))) + } yield (a, b) + + val genTwoLarge = for { + a <- weightedLong + b <- arbitrary[Long] suchThat (b => (abs(b) > Long.MaxValue / max(1, abs(a)))) + } yield (a, b) + + val genClose = for { + a <- weightedLong + if a != 0 + b <- choose(Long.MaxValue / a - 10, Long.MaxValue / a + 10) + } yield (a, b) + + val genBorderline = + frequency( + 1 -> (Long.MinValue, 0L), + 1 -> (Long.MinValue, 1L), + 1 -> (Long.MinValue, -1L), + 1 -> (0L, Long.MinValue), + 1 -> (1L, Long.MinValue), + 1 -> (-1L, Long.MinValue), + 90 -> genClose + ) + + def mul(a: Long, b: Long): Long = { + (fromNanos(a) * b).toNanos + } + + property("without overflow") = forAll(genTwoSmall) { case (a, b) => + a * b == mul(a, b) + } + + property("with overflow") = forAll(genTwoLarge) { case (a, b) => + try { mul(a, b); false } catch { case _: IllegalArgumentException => true } + } + + property("on overflow edge cases") = forAll(genBorderline) { case (a, b) => + val shouldFit = + a != Long.MinValue && // must fail due to illegal duration length + (b != Long.MinValue || a == 0) && // Long factor may only be MinValue if the duration is zero, otherwise the result will be illegal + (abs(b) <= Long.MaxValue / max(1, abs(a))) // check the rest against the “safe” division method + try { mul(a, b); shouldFit } + catch { case _: IllegalArgumentException => !shouldFit } + } +} |