diff --git a/ast/jvm/src/test/scala/jawn/ast/AstTestPlatform.scala b/ast/jvm/src/test/scala/jawn/ast/AstTestPlatform.scala index a6eb18f0..5b42adb1 100644 --- a/ast/jvm/src/test/scala/jawn/ast/AstTestPlatform.scala +++ b/ast/jvm/src/test/scala/jawn/ast/AstTestPlatform.scala @@ -23,8 +23,11 @@ package org.typelevel.jawn package ast import org.scalacheck.Prop +import Prop.{forAll, forAllNoShrink} -import Prop.forAll +import scala.util.Try + +import ArbitraryUtil.expNotationNums private[jawn] trait AstTestPlatform { self: AstTest => @@ -37,4 +40,10 @@ private[jawn] trait AstTestPlatform { self: AstTest => ) } + property(".asDouble") = forAllNoShrink { (expForm: (String, Double)) => + Prop( + JParser.parseUnsafe(expForm._1).getDouble == Try(JParser.parseUnsafe(expForm._1).asDouble).toOption && + JParser.parseUnsafe(expForm._1).asDouble == expForm._2 + ) + } } diff --git a/ast/shared/src/main/scala/jawn/ast/JValue.scala b/ast/shared/src/main/scala/jawn/ast/JValue.scala index 59c9afc3..2c20a838 100644 --- a/ast/shared/src/main/scala/jawn/ast/JValue.scala +++ b/ast/shared/src/main/scala/jawn/ast/JValue.scala @@ -254,13 +254,13 @@ case class DeferNum(s: String) extends JNum { lazy val n: Double = java.lang.Double.parseDouble(s) final override def getInt: Option[Int] = Some(n.toInt) - final override def getLong: Option[Long] = Some(util.parseLongUnsafe(s)) + final override def getLong: Option[Long] = Some(n.toLong) final override def getDouble: Option[Double] = Some(n) final override def getBigInt: Option[BigInt] = Some(BigDecimal(s).toBigInt) final override def getBigDecimal: Option[BigDecimal] = Some(BigDecimal(s)) final override def asInt: Int = n.toInt - final override def asLong: Long = util.parseLongUnsafe(s) + final override def asLong: Long = n.toLong final override def asDouble: Double = n final override def asBigInt: BigInt = BigDecimal(s).toBigInt final override def asBigDecimal: BigDecimal = BigDecimal(s) diff --git a/ast/shared/src/test/scala/jawn/ArbitraryUtil.scala b/ast/shared/src/test/scala/jawn/ArbitraryUtil.scala index 83280bcd..8c2e8876 100644 --- a/ast/shared/src/test/scala/jawn/ArbitraryUtil.scala +++ b/ast/shared/src/test/scala/jawn/ArbitraryUtil.scala @@ -62,4 +62,17 @@ object ArbitraryUtil { implicit lazy val arbitraryJValue: Arbitrary[JValue] = Arbitrary(jvalue()) + + // Valid JSON numbers with an exact double representation and in the Long range + + implicit lazy val expNotationNums: Arbitrary[(String, Double)] = Arbitrary[(String, Double)] { + Gen.oneOf( + ("2e3", 2e3), + ("2.5e0", 2.5e0), + ("2e+3", 2e+3), + ("2.5e-1", 2.5e-1), + ("9.223372036854776e18", 9.223372036854776e18), + ("-9.223372036854776e+18", -9.223372036854776e18) + ) + } } diff --git a/ast/shared/src/test/scala/jawn/AstTest.scala b/ast/shared/src/test/scala/jawn/AstTest.scala index e7adc509..a67ac3dc 100644 --- a/ast/shared/src/test/scala/jawn/AstTest.scala +++ b/ast/shared/src/test/scala/jawn/AstTest.scala @@ -23,10 +23,10 @@ package org.typelevel.jawn package ast import org.scalacheck.{Prop, Properties} -import scala.util.{Success, Try} +import scala.util.{Success, Try} import ArbitraryUtil._ -import Prop.forAll +import Prop.{forAll, forAllNoShrink} class AstTest extends Properties("AstTest") with AstTestPlatform { @@ -62,6 +62,13 @@ class AstTest extends Properties("AstTest") with AstTestPlatform { ) } + property(".asInt") = forAllNoShrink { (expForm: (String, Double)) => + Prop( + JParser.parseUnsafe(expForm._1).getInt == Try(JParser.parseUnsafe(expForm._1).asInt).toOption && + JParser.parseUnsafe(expForm._1).asInt == expForm._2.intValue() + ) + } + property(".getLong") = forAll { (n: Long) => Prop( JNum(n).getLong == Some(n) && @@ -69,6 +76,13 @@ class AstTest extends Properties("AstTest") with AstTestPlatform { ) } + property(".asLong") = forAllNoShrink { (expForm: (String, Double)) => + Prop( + JParser.parseUnsafe(expForm._1).getLong == Try(JParser.parseUnsafe(expForm._1).asLong).toOption && + JParser.parseUnsafe(expForm._1).asLong == expForm._2.longValue() + ) + } + property(".getBigInt") = forAll { (n: BigInt) => Prop( JNum(n.toString).getBigInt == Some(n) && @@ -76,6 +90,13 @@ class AstTest extends Properties("AstTest") with AstTestPlatform { ) } + property(".asBigInt") = forAllNoShrink { (expForm: (String, Double)) => + Prop( + JParser.parseUnsafe(expForm._1).getBigInt == Try(JParser.parseUnsafe(expForm._1).asBigInt).toOption && + JParser.parseUnsafe(expForm._1).asBigInt == BigDecimal(expForm._2).toBigInt() + ) + } + property(".getBigDecimal") = forAll { (n: BigDecimal) => if (Try(BigDecimal(n.toString)) == Success(n)) Prop( @@ -85,4 +106,11 @@ class AstTest extends Properties("AstTest") with AstTestPlatform { else Prop(true) } + + property(".asBigDecimal") = forAllNoShrink { (expForm: (String, Double)) => + Prop( + JParser.parseUnsafe(expForm._1).getBigDecimal == Try(JParser.parseUnsafe(expForm._1).asBigDecimal).toOption && + JParser.parseUnsafe(expForm._1).asBigDecimal == BigDecimal(expForm._2) + ) + } }