Skip to content

Commit

Permalink
Merge 92ecf11 into 3090b8c
Browse files Browse the repository at this point in the history
  • Loading branch information
ruippeixotog committed Sep 28, 2019
2 parents 3090b8c + 92ecf11 commit 8abe029
Show file tree
Hide file tree
Showing 15 changed files with 150 additions and 168 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Expand Up @@ -39,7 +39,7 @@ lazy val docs = (project in file("docs")).
def module(proj: Project) = proj.
enablePlugins(SbtOsgi, TutPlugin).
dependsOn(core).
dependsOn(tests % "test->test"). // In order to reuse thDerivationSuite scalacheck generators
dependsOn(tests % "test").
dependsOn(generic % "Tut"). // Allow auto-derivation in documentation
settings(commonSettings, tutTargetDirectory := baseDirectory.value)

Expand Down
@@ -1,11 +1,9 @@
package pureconfig.module.joda

import org.joda.time._
import org.scalacheck.Arbitrary
import JodaSuite._
import org.joda.time.format.{ DateTimeFormat, DateTimeFormatter }
import pureconfig.module.joda.configurable.ConfigurableSuite.{ dateTimeArbitrary, zoneIdArbitrary }
import pureconfig.BaseSuite
import pureconfig.module.joda.arbitrary._

class JodaSuite extends BaseSuite {

Expand All @@ -20,20 +18,3 @@ class JodaSuite extends BaseSuite {
checkReadString[DateTimeFormatter](
"yyyy-MM-dd'T'HH:mm:ss.SSSZZZ" -> DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"))
}

object JodaSuite {
implicit val instantArbitrary: Arbitrary[Instant] =
Arbitrary(Arbitrary.arbitrary[Long].map(new Instant(_)))

implicit val intervalArbitrary: Arbitrary[Interval] =
Arbitrary(Arbitrary.arbitrary[(DateTime, DateTime)]
.map { i =>
val (from, to) = if (i._1.isBefore(i._2)) i else i.swap
// Comparing new Interval(foo) with Interval.parseWithOffset(foo) will return false
// See http://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html#parseWithOffset-java.lang.String-
Interval.parseWithOffset(new Interval(from, to).toString)
})

implicit val durationArbitrary: Arbitrary[Duration] =
Arbitrary(Arbitrary.arbitrary[Long].map(new Duration(_)))
}
@@ -0,0 +1,69 @@
package pureconfig.module.joda

import scala.collection.JavaConverters._

import org.joda.time._
import org.scalacheck.{ Arbitrary, Gen }
import pureconfig.gen._

package object arbitrary {
private def nanoToMilli(n: Int): Int = n / 1000000

implicit val instantArbitrary: Arbitrary[Instant] =
Arbitrary(Arbitrary.arbitrary[Long].map(new Instant(_)))

implicit val intervalArbitrary: Arbitrary[Interval] =
Arbitrary(Arbitrary.arbitrary[(DateTime, DateTime)]
.map { i =>
val (from, to) = if (i._1.isBefore(i._2)) i else i.swap
// Comparing new Interval(foo) with Interval.parseWithOffset(foo) will return false
// See http://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html#parseWithOffset-java.lang.String-
Interval.parseWithOffset(new Interval(from, to).toString)
})

implicit val durationArbitrary: Arbitrary[Duration] =
Arbitrary(Arbitrary.arbitrary[Long].map(new Duration(_)))

implicit val localTimeArbitrary: Arbitrary[LocalTime] = Arbitrary(
genLocalTime.map { t =>
new LocalTime(t.getHour, t.getMinute, t.getSecond, nanoToMilli(t.getNano))
})

implicit val localDateArbitrary: Arbitrary[LocalDate] = Arbitrary(
genLocalDate.map { d =>
new LocalDate(d.getYear, d.getMonthValue, d.getDayOfMonth)
})

implicit val localDateTimeArbitrary: Arbitrary[LocalDateTime] = Arbitrary(
genLocalDateTime.map { d =>
new LocalDateTime(
d.getYear, d.getMonthValue, d.getDayOfMonth,
d.getHour, d.getMinute, d.getSecond, nanoToMilli(d.getNano))
})

implicit val monthDayArbitrary: Arbitrary[MonthDay] = Arbitrary(
genMonthDay.map { m =>
new MonthDay(m.getMonthValue, m.getDayOfMonth)
})

implicit val yearMonthArbitrary: Arbitrary[YearMonth] = Arbitrary(
genYearMonth.map { y =>
new YearMonth(y.getYear, y.getMonthValue)
})

implicit val zoneIdArbitrary: Arbitrary[DateTimeZone] =
Arbitrary(Gen.oneOf(DateTimeZone.getAvailableIDs.asScala.toSeq).map(DateTimeZone.forID))

implicit val dateTimeArbitrary: Arbitrary[DateTime] =
Arbitrary(
for {
zoneId <- zoneIdArbitrary.arbitrary
localDateTime <- localDateTimeArbitrary.arbitrary if !zoneId.isLocalDateTimeGap(localDateTime)
} yield localDateTime.toDateTime(zoneId))

implicit val periodArbitrary: Arbitrary[Period] =
Arbitrary(Arbitrary.arbitrary[Int].map { i =>
// Generated large longs crash Period constructor internally
new Period(i.toLong)
})
}
Expand Up @@ -2,12 +2,8 @@ package pureconfig.module.joda.configurable

import org.joda.time._
import org.joda.time.format.{ DateTimeFormat, ISOPeriodFormat, PeriodFormatter }
import org.scalacheck.{ Arbitrary, Gen }
import ConfigurableSuite._
import pureconfig.configurable.{ ConfigurableSuite => JTime }
import scala.collection.JavaConverters._

import pureconfig.BaseSuite
import pureconfig.module.joda.arbitrary._

class ConfigurableSuite extends BaseSuite {

Expand Down Expand Up @@ -39,50 +35,3 @@ class ConfigurableSuite extends BaseSuite {
implicit val periodInstance = periodConfigConvert(periodFormatter)
checkArbitrary[Period]
}

object ConfigurableSuite {
private def nanoToMilli(n: Int): Int = n / 1000000

implicit val localTimeArbitrary: Arbitrary[LocalTime] = Arbitrary(
JTime.localTimeArbitrary.arbitrary.map { t =>
new LocalTime(t.getHour, t.getMinute, t.getSecond, nanoToMilli(t.getNano))
})

implicit val localDateArbitrary: Arbitrary[LocalDate] = Arbitrary(
JTime.localDateArbitrary.arbitrary.map { d =>
new LocalDate(d.getYear, d.getMonthValue, d.getDayOfMonth)
})

implicit val localDateTimeArbitrary: Arbitrary[LocalDateTime] = Arbitrary(
JTime.localDateTimeArbitrary.arbitrary.map { d =>
new LocalDateTime(
d.getYear, d.getMonthValue, d.getDayOfMonth,
d.getHour, d.getMinute, d.getSecond, nanoToMilli(d.getNano))
})

implicit val monthDayArbitrary: Arbitrary[MonthDay] = Arbitrary(
JTime.monthDayArbitrary.arbitrary.map { m =>
new MonthDay(m.getMonthValue, m.getDayOfMonth)
})

implicit val yearMonthArbitrary: Arbitrary[YearMonth] = Arbitrary(
JTime.yearMonthArbitrary.arbitrary.map { y =>
new YearMonth(y.getYear, y.getMonthValue)
})

implicit val zoneIdArbitrary: Arbitrary[DateTimeZone] =
Arbitrary(Gen.oneOf(DateTimeZone.getAvailableIDs.asScala.toSeq).map(DateTimeZone.forID))

implicit val dateTimeArbitrary: Arbitrary[DateTime] =
Arbitrary(
for {
zoneId <- zoneIdArbitrary.arbitrary
localDateTime <- localDateTimeArbitrary.arbitrary if !zoneId.isLocalDateTimeGap(localDateTime)
} yield localDateTime.toDateTime(zoneId))

implicit val periodArbitrary: Arbitrary[Period] =
Arbitrary(Arbitrary.arbitrary[Int].map { i =>
// Generated large longs crash Period constructor internally
new Period(i.toLong)
})
}
6 changes: 3 additions & 3 deletions project/Dependencies.scala
Expand Up @@ -17,8 +17,8 @@ object Dependencies {
val typesafeConfig = "com.typesafe" % "config" % Version.typesafeConfig

// testing libraries
val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest % "test"
val scalaCheck = "org.scalacheck" %% "scalacheck" % Version.scalaCheck % "test"
val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest
val scalaCheck = "org.scalacheck" %% "scalacheck" % Version.scalaCheck
val scalaCheckShapeless =
"com.github.alexarchambault" %% s"scalacheck-shapeless_1.14" % Version.scalaCheckShapeless % "test"
"com.github.alexarchambault" %% s"scalacheck-shapeless_1.14" % Version.scalaCheckShapeless
}
2 changes: 1 addition & 1 deletion tests/build.sbt
Expand Up @@ -7,6 +7,6 @@ crossScalaVersions ~= { _ :+ "2.13.0" }
libraryDependencies ++= Seq(
scalaTest,
scalaCheck,
scalaCheckShapeless)
scalaCheckShapeless % "test")

skip in publish := true
Expand Up @@ -23,8 +23,7 @@ trait ConfigConvertChecks { this: FlatSpec with Matchers with ScalaCheckDrivenPr
* Note that this method doesn't check all the values but only the values that can be created by `Arbitrary[T]` and
* only the `ConfigValue` created by `ConfigConvert[T].to`. While `Arbitrary[T]` is usually comprehensive,
* `ConfigConvert[T].from` could support different kind of values that `ConfigConvert[T].to` doesn't produce
* because, for instance, multiple representation of `t: T` are possible. Use [[checkRead()]] for those
* representations.
* because, for instance, multiple representation of `t: T` are possible. Use [[checkRead]] for those representations.
*/
def checkArbitrary[T](implicit cc: Derivation[ConfigConvert[T]], arb: Arbitrary[T], tpe: TypeTag[T], equality: Equality[T]): Unit =
it should s"read an arbitrary ${tpe.tpe}" in forAll { t: T =>
Expand Down Expand Up @@ -65,7 +64,7 @@ trait ConfigConvertChecks { this: FlatSpec with Matchers with ScalaCheckDrivenPr
}
}

/** Similar to [[checkRead()]] but work on ConfigValues of type String */
/** Similar to [[checkRead]] but work on ConfigValues of type String */
def checkReadString[T: ConfigReader: TypeTag: Equality](strsToValues: (String, T)*): Unit =
checkRead[T](strsToValues.map { case (s, t) => ConfigValueFactory.fromAnyRef(s) -> t }: _*)

Expand All @@ -80,7 +79,7 @@ trait ConfigConvertChecks { this: FlatSpec with Matchers with ScalaCheckDrivenPr
}
}

/** Similar to [[checkWrite()]] but work on ConfigValues of type String */
/** Similar to [[checkWrite]] but work on ConfigValues of type String */
def checkWriteString[T: ConfigWriter: TypeTag: Equality](valuesToStrs: (T, String)*): Unit =
checkWrite[T](valuesToStrs.map { case (t, s) => t -> ConfigValueFactory.fromAnyRef(s) }: _*)

Expand All @@ -94,7 +93,7 @@ trait ConfigConvertChecks { this: FlatSpec with Matchers with ScalaCheckDrivenPr
checkWrite[T](reprsValues.map(_.swap): _*)
}

/** Similar to [[checkReadWrite()]] but work on ConfigValues of type String */
/** Similar to [[checkReadWrite]] but work on ConfigValues of type String */
def checkReadWriteString[T: ConfigReader: ConfigWriter: TypeTag: Equality](strsValues: (String, T)*): Unit = {
checkReadString[T](strsValues: _*)
checkWriteString[T](strsValues.map(_.swap): _*)
Expand All @@ -104,7 +103,7 @@ trait ConfigConvertChecks { this: FlatSpec with Matchers with ScalaCheckDrivenPr
* Check that `cc` returns error of type `E` when trying to read each value passed with `values`
*
* @param values the values that should not be conver
* @param cr the [[ConfigConvert]] to test
* @param cr the `ConfigConvert` to test
*/
def checkFailure[T, E <: FailureReason](values: ConfigValue*)(implicit cr: ConfigReader[T], tpe: TypeTag[T], eTag: ClassTag[E]): Unit =
for (value <- values) {
Expand Down
Expand Up @@ -9,8 +9,6 @@ package object arbitrary {
implicit val arbJavaDuration = Arbitrary(genJavaDuration)
implicit val arbFiniteDuration = Arbitrary(genFiniteDuration)
implicit val arbInstant = Arbitrary(genInstant)
implicit val arbZoneId = Arbitrary(genZoneId)
implicit val arbZoneOffset = Arbitrary(genZoneOffset)
implicit val arbPeriod = Arbitrary(genPeriod)
implicit val arbYear = Arbitrary(genYear)
implicit val arbUUID = Arbitrary(Gen.uuid)
Expand All @@ -19,4 +17,15 @@ package object arbitrary {
implicit val arbPercentage = Arbitrary(genPercentage)
implicit val arbJavaBigDecimal = Arbitrary(genJavaBigDecimal)
implicit val arbJavaBigInteger = Arbitrary(genBigInt)

implicit val arbLocalTime = Arbitrary(genLocalTime)
implicit val arbLocalDate = Arbitrary(genLocalDate)
implicit val arbLocalDateTime = Arbitrary(genLocalDateTime)
implicit val arbMonthDay = Arbitrary(genMonthDay)
implicit val arbZoneOffset = Arbitrary(genZoneOffset)
implicit val arbOffsetDateTime = Arbitrary(genOffsetDateTime)
implicit val arbOffsetTime = Arbitrary(genOffsetTime)
implicit val arbYearMonth = Arbitrary(genYearMonth)
implicit val arbZoneId = Arbitrary(genZoneId)
implicit val arbZonedDateTime = Arbitrary(genZonedDateTime)
}
Expand Up @@ -36,22 +36,13 @@ package object gen {
val genInstant: Gen[Instant] =
Gen.choose(Instant.MIN.getEpochSecond, Instant.MAX.getEpochSecond).map(Instant.ofEpochSecond)

val genZoneId: Gen[ZoneId] =
Gen.oneOf(ZoneId.getAvailableZoneIds.asScala.toSeq).map(ZoneId.of)

val genZoneOffset: Gen[ZoneOffset] =
Gen.choose(ZoneOffset.MIN.getTotalSeconds, ZoneOffset.MAX.getTotalSeconds).map(ZoneOffset.ofTotalSeconds)

val genPeriod: Gen[Period] =
for {
years <- Arbitrary.arbInt.arbitrary
months <- Arbitrary.arbInt.arbitrary
days <- Arbitrary.arbInt.arbitrary
} yield Period.of(years, months, days)

val genYear: Gen[Year] =
Gen.choose(Year.MIN_VALUE, Year.MAX_VALUE).map(Year.of)

val genPath: Gen[Path] =
Gen.nonEmptyListOf(Gen.alphaNumStr).map(parts => parts.map(str => Paths.get(str)).reduce(_ resolve _))

Expand All @@ -64,4 +55,61 @@ package object gen {
val genJavaBigDecimal: Gen[JavaBigDecimal] = Arbitrary.arbitrary[BigDecimal].map(_.bigDecimal)

val genBigInt: Gen[BigInteger] = Arbitrary.arbitrary[BigInt].map(_.bigInteger)

val genHour: Gen[Int] = Gen.chooseNum(0, 23)
val genMinute: Gen[Int] = Gen.chooseNum(0, 59)
val genSecond: Gen[Int] = Gen.chooseNum(0, 59)
val genNano: Gen[Int] = Gen.chooseNum(0, 999999999)
val genYearInt: Gen[Int] = Gen.chooseNum(1970, 2999)
val genMonth: Gen[Int] = Gen.chooseNum(1, 12)

val genLocalTime: Gen[LocalTime] = for {
hour <- genHour
minute <- genMinute
second <- genSecond
nano <- genNano
} yield LocalTime.of(hour, minute, second, nano)

val genLocalDate: Gen[LocalDate] = for {
year <- genYearInt
month <- genMonth
day <- Gen.chooseNum(1, java.time.YearMonth.of(year, month).lengthOfMonth())
} yield LocalDate.of(year, month, day)

val genLocalDateTime: Gen[LocalDateTime] = for {
date <- genLocalDate
time <- genLocalTime
} yield date.atTime(time)

val genMonthDay: Gen[MonthDay] =
genLocalDate.map(date => MonthDay.of(date.getMonthValue, date.getDayOfMonth))

val genZoneOffset: Gen[ZoneOffset] =
Gen.choose(ZoneOffset.MIN.getTotalSeconds, ZoneOffset.MAX.getTotalSeconds).map(ZoneOffset.ofTotalSeconds)

val genOffsetDateTime: Gen[OffsetDateTime] = for {
localDateTime <- genLocalDateTime
offset <- genZoneOffset
} yield OffsetDateTime.of(localDateTime, offset)

val genOffsetTime: Gen[OffsetTime] = for {
localTime <- genLocalTime
offset <- genZoneOffset
} yield OffsetTime.of(localTime, offset)

val genYear: Gen[Year] =
Gen.choose(Year.MIN_VALUE, Year.MAX_VALUE).map(Year.of)

val genYearMonth: Gen[YearMonth] = for {
year <- genYearInt
month <- genMonth
} yield YearMonth.of(year, month)

val genZoneId: Gen[ZoneId] =
Gen.oneOf(ZoneId.getAvailableZoneIds.asScala.toSeq).map(ZoneId.of)

val genZonedDateTime: Gen[ZonedDateTime] = for {
localDateTime <- genLocalDateTime
zoneId <- genZoneId.suchThat(_ != ZoneId.of("GMT0")) // Avoid JDK-8138664
} yield ZonedDateTime.of(localDateTime, zoneId)
}

0 comments on commit 8abe029

Please sign in to comment.