aboutsummaryrefslogtreecommitdiff
path: root/core-types
diff options
context:
space:
mode:
authorJakob Odersky <jakob@driver.xyz>2018-10-04 13:52:14 -0700
committerJakob Odersky <jakob@odersky.com>2018-10-09 16:19:39 -0700
commit477804e21c3c61666a48b74f17caef04233c2363 (patch)
tree0f12c52e34850cac4ddeab99ae8b5d761f2dd3a3 /core-types
parente67f49c20c6901bf77bcfb735254e44dc70c0cee (diff)
downloaddriver-core-477804e21c3c61666a48b74f17caef04233c2363.tar.gz
driver-core-477804e21c3c61666a48b74f17caef04233c2363.tar.bz2
driver-core-477804e21c3c61666a48b74f17caef04233c2363.zip
Fix dependencies in tests to accomodate project split
Diffstat (limited to 'core-types')
-rw-r--r--core-types/src/main/scala/xyz/driver/core/deprecations.scala5
-rw-r--r--core-types/src/main/scala/xyz/driver/core/generators.scala143
2 files changed, 148 insertions, 0 deletions
diff --git a/core-types/src/main/scala/xyz/driver/core/deprecations.scala b/core-types/src/main/scala/xyz/driver/core/deprecations.scala
new file mode 100644
index 0000000..401e6c6
--- /dev/null
+++ b/core-types/src/main/scala/xyz/driver/core/deprecations.scala
@@ -0,0 +1,5 @@
+package xyz.driver.core.rest
+
+package object errors {
+ //type DatabaseException = xyz.driver.core.errors.DatabaseException
+}
diff --git a/core-types/src/main/scala/xyz/driver/core/generators.scala b/core-types/src/main/scala/xyz/driver/core/generators.scala
new file mode 100644
index 0000000..d00b6dd
--- /dev/null
+++ b/core-types/src/main/scala/xyz/driver/core/generators.scala
@@ -0,0 +1,143 @@
+package xyz.driver.core
+
+import enumeratum._
+import java.math.MathContext
+import java.time.{Instant, LocalDate, ZoneOffset}
+import java.util.UUID
+
+import xyz.driver.core.time.{Time, TimeOfDay, TimeRange}
+import xyz.driver.core.date.{Date, DayOfWeek}
+
+import scala.reflect.ClassTag
+import scala.util.Random
+import eu.timepit.refined.refineV
+import eu.timepit.refined.api.Refined
+import eu.timepit.refined.collection._
+
+object generators {
+
+ private val random = new Random
+ import random._
+ private val secureRandom = new java.security.SecureRandom()
+
+ private val DefaultMaxLength = 10
+ private val StringLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ".toSet
+ private val NonAmbigiousCharacters = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"
+ private val Numbers = "0123456789"
+
+ private def nextTokenString(length: Int, chars: IndexedSeq[Char]): String = {
+ val builder = new StringBuilder
+ for (_ <- 0 until length) {
+ builder += chars(secureRandom.nextInt(chars.length))
+ }
+ builder.result()
+ }
+
+ /** Creates a random invitation token.
+ *
+ * This token is meant fo human input and avoids using ambiguous characters such as 'O' and '0'. It
+ * therefore contains less entropy and is not meant to be used as a cryptographic secret. */
+ @deprecated(
+ "The term 'token' is too generic and security and readability conventions are not well defined. " +
+ "Services should implement their own version that suits their security requirements.",
+ "1.11.0"
+ )
+ def nextToken(length: Int): String = nextTokenString(length, NonAmbigiousCharacters)
+
+ @deprecated(
+ "The term 'token' is too generic and security and readability conventions are not well defined. " +
+ "Services should implement their own version that suits their security requirements.",
+ "1.11.0"
+ )
+ def nextNumericToken(length: Int): String = nextTokenString(length, Numbers)
+
+ def nextInt(maxValue: Int, minValue: Int = 0): Int = random.nextInt(maxValue - minValue) + minValue
+
+ def nextBoolean(): Boolean = random.nextBoolean()
+
+ def nextDouble(): Double = random.nextDouble()
+
+ def nextId[T](): Id[T] = Id[T](nextUuid().toString)
+
+ def nextId[T](maxLength: Int): Id[T] = Id[T](nextString(maxLength))
+
+ def nextNumericId[T](): Id[T] = Id[T](nextLong.abs.toString)
+
+ def nextNumericId[T](maxValue: Int): Id[T] = Id[T](nextInt(maxValue).toString)
+
+ def nextName[T](maxLength: Int = DefaultMaxLength): Name[T] = Name[T](nextString(maxLength))
+
+ def nextNonEmptyName[T](maxLength: Int = DefaultMaxLength): NonEmptyName[T] =
+ NonEmptyName[T](nextNonEmptyString(maxLength))
+
+ def nextUuid(): UUID = java.util.UUID.randomUUID
+
+ def nextRevision[T](): Revision[T] = Revision[T](nextUuid().toString)
+
+ def nextString(maxLength: Int = DefaultMaxLength): String =
+ (oneOf[Char](StringLetters) +: arrayOf(oneOf[Char](StringLetters), maxLength - 1)).mkString
+
+ def nextNonEmptyString(maxLength: Int = DefaultMaxLength): String Refined NonEmpty = {
+ refineV[NonEmpty](
+ (oneOf[Char](StringLetters) +: arrayOf(oneOf[Char](StringLetters), maxLength - 1)).mkString
+ ).right.get
+ }
+
+ def nextOption[T](value: => T): Option[T] = if (nextBoolean()) Option(value) else None
+
+ def nextPair[L, R](left: => L, right: => R): (L, R) = (left, right)
+
+ def nextTriad[F, S, T](first: => F, second: => S, third: => T): (F, S, T) = (first, second, third)
+
+ def nextInstant(): Instant = Instant.ofEpochMilli(math.abs(nextLong() % System.currentTimeMillis))
+
+ def nextTime(): Time = nextInstant()
+
+ def nextTimeOfDay: TimeOfDay = TimeOfDay(java.time.LocalTime.MIN.plusSeconds(nextLong), java.util.TimeZone.getDefault)
+
+ def nextTimeRange(): TimeRange = {
+ val oneTime = nextTime()
+ val anotherTime = nextTime()
+
+ TimeRange(
+ Time(scala.math.min(oneTime.millis, anotherTime.millis)),
+ Time(scala.math.max(oneTime.millis, anotherTime.millis)))
+ }
+
+ def nextDate(): Date = nextTime().toDate(java.util.TimeZone.getTimeZone("UTC"))
+
+ def nextLocalDate(): LocalDate = nextInstant().atZone(ZoneOffset.UTC).toLocalDate
+
+ def nextDayOfWeek(): DayOfWeek = oneOf(DayOfWeek.All)
+
+ def nextBigDecimal(multiplier: Double = 1000000.00, precision: Int = 2): BigDecimal =
+ BigDecimal(multiplier * nextDouble, new MathContext(precision))
+
+ def oneOf[T](items: T*): T = oneOf(items.toSet)
+
+ def oneOf[T](items: Set[T]): T = items.toSeq(nextInt(items.size))
+
+ def oneOf[T <: EnumEntry](enum: Enum[T]): T = oneOf(enum.values: _*)
+
+ def arrayOf[T: ClassTag](generator: => T, maxLength: Int = DefaultMaxLength, minLength: Int = 0): Array[T] =
+ Array.fill(nextInt(maxLength, minLength))(generator)
+
+ def seqOf[T](generator: => T, maxLength: Int = DefaultMaxLength, minLength: Int = 0): Seq[T] =
+ Seq.fill(nextInt(maxLength, minLength))(generator)
+
+ def vectorOf[T](generator: => T, maxLength: Int = DefaultMaxLength, minLength: Int = 0): Vector[T] =
+ Vector.fill(nextInt(maxLength, minLength))(generator)
+
+ def listOf[T](generator: => T, maxLength: Int = DefaultMaxLength, minLength: Int = 0): List[T] =
+ List.fill(nextInt(maxLength, minLength))(generator)
+
+ def setOf[T](generator: => T, maxLength: Int = DefaultMaxLength, minLength: Int = 0): Set[T] =
+ seqOf(generator, maxLength, minLength).toSet
+
+ def mapOf[K, V](
+ keyGenerator: => K,
+ valueGenerator: => V,
+ maxLength: Int = DefaultMaxLength,
+ minLength: Int = 0): Map[K, V] =
+ seqOf(nextPair(keyGenerator, valueGenerator), maxLength, minLength).toMap
+}