diff options
Diffstat (limited to 'test/files/jvm')
-rw-r--r-- | test/files/jvm/duration-tck.scala | 236 |
1 files changed, 157 insertions, 79 deletions
diff --git a/test/files/jvm/duration-tck.scala b/test/files/jvm/duration-tck.scala index 679712aa59..aa1ac50078 100644 --- a/test/files/jvm/duration-tck.scala +++ b/test/files/jvm/duration-tck.scala @@ -10,7 +10,13 @@ import java.util.concurrent.TimeUnit._ object Test extends App { implicit class Assert(val left: Any) extends AnyVal { - def =!=(right: Any) = assert(left == right, s"$left was not equal to $right") + import Duration.Undefined + def mustBe(right: Any) = right match { + case r: Double if r.isNaN => assert(left.asInstanceOf[Double].isNaN, s"$left was not NaN") + case r: Double if r == 0 && r.compareTo(0) == -1 => assert(left == 0 && left.asInstanceOf[Double].compareTo(0) == -1, s"$left was not -0.0") + case Undefined => assert(left.asInstanceOf[AnyRef] eq Undefined, s"$left was not Undefined") + case _ => assert(left == right, s"$left was not equal to $right") + } } def intercept[T <: Exception : ClassTag](code: => Unit) = @@ -19,89 +25,161 @@ object Test extends App { case ex: Exception => if (classTag[T].runtimeClass isAssignableFrom ex.getClass) () else throw ex } - { // test field ops - val zero = 0 seconds - val one = 1 second - val two = one + one - val three = 3 * one - (0 * one) =!= (zero) - (2 * one) =!= (two) - (three - two) =!= (one) - (three / 3) =!= (one) - (two / one) =!= (2) - (one + zero) =!= (one) - (one / 1000000) =!= (1.micro) - } + val zero = 0 seconds + val one = 1 second + val two = one + one + val three = 3 * one + val inf = Duration.Inf + val minf = Duration.MinusInf + val undef = Duration.Undefined + val inputs = List(zero, one, inf, minf, undef) + val nan = Double.NaN - { // test infinities - val one = 1.second - val inf = Duration.Inf - val minf = Duration.MinusInf - (-inf) =!= (minf) - intercept[IllegalArgumentException] { minf + inf } - intercept[IllegalArgumentException] { inf - inf } - intercept[IllegalArgumentException] { inf + minf } - intercept[IllegalArgumentException] { minf - minf } - (inf + inf) =!= (inf) - (inf - minf) =!= (inf) - (minf - inf) =!= (minf) - (minf + minf) =!= (minf) - assert(inf == inf) - assert(minf == minf) - inf.compareTo(inf) =!= (0) - inf.compareTo(one) =!= (1) - minf.compareTo(minf) =!= (0) - minf.compareTo(one) =!= (-1) - assert(inf != minf) - assert(minf != inf) - assert(one != inf) - assert(minf != one) - inf =!= (minf * -1d) - inf =!= (minf / -1d) - } + // test field ops + one.isFinite mustBe true + 0 * one mustBe zero + 2 * one mustBe two + three - two mustBe one + three / 3 mustBe one + two / one mustBe 2 + one + zero mustBe one + one / 1000000 mustBe 1.micro + + + // test infinities + + inf.isFinite mustBe false + minf.isFinite mustBe false + + inf mustBe inf + minf mustBe minf + -inf mustBe minf + -minf mustBe inf + + minf + inf mustBe undef + inf - inf mustBe undef + inf + minf mustBe undef + minf - minf mustBe undef + + inf + inf mustBe inf + inf - minf mustBe inf + minf - inf mustBe minf + minf + minf mustBe minf + + inf.compareTo(inf) mustBe 0 + inf.compareTo(one) mustBe 1 + inf.compareTo(minf) mustBe 1 + minf.compareTo(minf) mustBe 0 + minf.compareTo(one) mustBe -1 + minf.compareTo(inf) mustBe -1 + + assert(inf != minf) + assert(minf != inf) + assert(one != inf) + assert(minf != one) + + inf mustBe (minf * -1d) + inf mustBe (minf / -1d) + + one / inf mustBe 0d + -one / inf mustBe -0d + one / minf mustBe -0d + -one / minf mustBe 0d + + inputs filterNot (_.isFinite) foreach (x => x / zero mustBe x.toUnit(DAYS)) + inputs filterNot (_.isFinite) foreach (_ * 0d mustBe undef) + inputs filterNot (_.isFinite) foreach (x => x * Double.PositiveInfinity mustBe x) + inputs filterNot (_.isFinite) foreach (x => x * Double.NegativeInfinity mustBe -x) + + inf.toUnit(SECONDS) mustBe Double.PositiveInfinity + minf.toUnit(MINUTES) mustBe Double.NegativeInfinity + Duration.fromNanos(Double.PositiveInfinity) mustBe inf + Duration.fromNanos(Double.NegativeInfinity) mustBe minf + - { // test overflow protection - for (unit ← Seq(DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS)) { - val x = unit.convert(Long.MaxValue, NANOSECONDS) - val dur = Duration(x, unit) - val mdur = Duration(-x, unit) - -mdur =!= (dur) - intercept[IllegalArgumentException] { Duration(x + 10000000d, unit) } - intercept[IllegalArgumentException] { Duration(-x - 10000000d, unit) } - if (unit != NANOSECONDS) { - intercept[IllegalArgumentException] { Duration(x + 1, unit) } - intercept[IllegalArgumentException] { Duration(-x - 1, unit) } - } - intercept[IllegalArgumentException] { dur + 1.day } - intercept[IllegalArgumentException] { mdur - 1.day } - intercept[IllegalArgumentException] { dur * 1.1 } - intercept[IllegalArgumentException] { mdur * 1.1 } - intercept[IllegalArgumentException] { dur * 2.1 } - intercept[IllegalArgumentException] { mdur * 2.1 } - intercept[IllegalArgumentException] { dur / 0.9 } - intercept[IllegalArgumentException] { mdur / 0.9 } - intercept[IllegalArgumentException] { dur / 0.4 } - intercept[IllegalArgumentException] { mdur / 0.4 } - Duration(x + unit.toString.toLowerCase) - Duration("-" + x + unit.toString.toLowerCase) - intercept[IllegalArgumentException] { Duration("%.0f".format(x + 10000000d) + unit.toString.toLowerCase) } - intercept[IllegalArgumentException] { Duration("-%.0f".format(x + 10000000d) + unit.toString.toLowerCase) } + // test undefined & NaN + + undef.isFinite mustBe false + -undef mustBe undef + assert(undef != undef) + assert(undef eq undef) + + inputs foreach (_ + undef mustBe undef) + inputs foreach (_ - undef mustBe undef) + inputs foreach (_ / undef mustBe nan) + inputs foreach (_ / nan mustBe undef) + inputs foreach (_ * nan mustBe undef) + inputs foreach (undef + _ mustBe undef) + inputs foreach (undef - _ mustBe undef) + inputs foreach (undef / _ mustBe nan) + inputs filter (_.isFinite) foreach (x => x / zero mustBe x.toUnit(SECONDS) / 0d) + + inputs filterNot (_ eq undef) foreach (_ compareTo undef mustBe -1) + inputs filterNot (_ eq undef) foreach (undef compareTo _ mustBe 1) + undef compare undef mustBe 0 + + undef.toUnit(DAYS) mustBe nan + Duration.fromNanos(nan) mustBe undef + + + // test overflow protection + for (unit ← Seq(DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS)) { + val x = unit.convert(Long.MaxValue, NANOSECONDS) + val dur = Duration(x, unit) + val mdur = Duration(-x, unit) + -mdur mustBe (dur) + intercept[IllegalArgumentException] { Duration(x + 10000000d, unit) } + intercept[IllegalArgumentException] { Duration(-x - 10000000d, unit) } + if (unit != NANOSECONDS) { + intercept[IllegalArgumentException] { Duration(x + 1, unit) } + intercept[IllegalArgumentException] { Duration(-x - 1, unit) } } + intercept[IllegalArgumentException] { dur + 1.day } + intercept[IllegalArgumentException] { mdur - 1.day } + intercept[IllegalArgumentException] { dur * 1.1 } + intercept[IllegalArgumentException] { mdur * 1.1 } + intercept[IllegalArgumentException] { dur * 2.1 } + intercept[IllegalArgumentException] { mdur * 2.1 } + intercept[IllegalArgumentException] { dur / 0.9 } + intercept[IllegalArgumentException] { mdur / 0.9 } + intercept[IllegalArgumentException] { dur / 0.4 } + intercept[IllegalArgumentException] { mdur / 0.4 } + Duration(x + unit.toString.toLowerCase) + Duration("-" + x + unit.toString.toLowerCase) + intercept[IllegalArgumentException] { Duration("%.0f".format(x + 10000000d) + unit.toString.toLowerCase) } + intercept[IllegalArgumentException] { Duration("-%.0f".format(x + 10000000d) + unit.toString.toLowerCase) } } + intercept[IllegalArgumentException] { Duration.fromNanos(1e20) } + intercept[IllegalArgumentException] { Duration.fromNanos(-1e20) } + - { // test Deadline - val dead = 2.seconds.fromNow - val dead2 = 2 seconds fromNow - // view bounds vs. very local type inference vs. operator precedence: sigh - assert(dead.timeLeft > (1 second: Duration)) - assert(dead2.timeLeft > (1 second: Duration)) - Thread.sleep(1.second.toMillis) - assert(dead.timeLeft < (1 second: Duration)) - assert(dead2.timeLeft < (1 second: Duration)) - } + // test precision + 1.second + 1.millisecond mustBe 1001.milliseconds + 100000.days + 1.nanosecond mustBe 8640000000000000001L.nanoseconds + 1.5.seconds.toSeconds mustBe 1 + (-1.5).seconds.toSeconds mustBe -1 + - { // check statically retaining finite-ness - val d: FiniteDuration = 1.second * 2 / 1.4 mul 1.1 div 2.1 plus 3.seconds minus 1.millisecond min 1.second max 1.second - } + // test unit stability + 1000.millis.unit mustBe MILLISECONDS + (1000.millis + 0.days).unit mustBe MILLISECONDS + 1.second.unit mustBe SECONDS + (1.second + 1.millisecond).unit mustBe MILLISECONDS + + + // test Deadline + val dead = 2.seconds.fromNow + val dead2 = 2 seconds fromNow + // view bounds vs. very local type inference vs. operator precedence: sigh + assert(dead.timeLeft > (1 second: Duration)) + assert(dead2.timeLeft > (1 second: Duration)) + Thread.sleep(1.second.toMillis) + assert(dead.timeLeft < (1 second: Duration)) + assert(dead2.timeLeft < (1 second: Duration)) + + + // check statically retaining finite-ness + val finiteDuration: FiniteDuration = 1.second plus 3.seconds minus 1.millisecond min 1.second max 1.second + } |