Skip to content

Commit

Permalink
Merge pull request #379 from kusamakura/topic/parseable-predicates
Browse files Browse the repository at this point in the history
Valid number string predicates
  • Loading branch information
fthomas authored Dec 22, 2017
2 parents 32abf9f + 40c0cc9 commit 96897dc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
3 changes: 1 addition & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ lazy val moduleJvmSettings = Def.settings(
"eu.timepit.refined.NumericValidate.moduloValidateNat"),
ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.scalacheck.util.OurMath"),
ProblemFilters.exclude[MissingClassProblem]("eu.timepit.refined.scalacheck.util.OurMath$"),
ProblemFilters.exclude[ReversedMissingMethodProblem](
"eu.timepit.refined.StringValidate.ipv4Validate"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("eu.timepit.refined.StringValidate.*"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("eu.timepit.refined.types.*")
)
}
Expand Down
30 changes: 30 additions & 0 deletions modules/core/shared/src/main/scala/eu/timepit/refined/string.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ object string extends StringValidate with StringInference {

/** Predicate that checks if a `String` is a valid XPath expression. */
final case class XPath()

/** Predicate that checks if a `String` can be a valid `Int`. */
final case class ValidInt()

/** Predicate that checks if a `String` can be a valid `Long`. */
final case class ValidLong()

/** Predicate that checks if a `String` can be a valid `Double`. */
final case class ValidDouble()

/** Predicate that checks if a `String` can be a valid `BigInt`. */
final case class ValidBigInt()

/** Predicate that checks if a `String` can be a valid `BigDecimal`. */
final case class ValidBigDecimal()
}

private[refined] trait StringValidate {
Expand Down Expand Up @@ -100,6 +115,21 @@ private[refined] trait StringValidate {
implicit def xpathValidate: Validate.Plain[String, XPath] =
Validate
.fromPartial(javax.xml.xpath.XPathFactory.newInstance().newXPath().compile, "XPath", XPath())

implicit def validIntValidate: Validate.Plain[String, ValidInt] =
Validate.fromPartial(_.toInt, "ValidInt", ValidInt())

implicit def validLongValidate: Validate.Plain[String, ValidLong] =
Validate.fromPartial(_.toLong, "ValidLong", ValidLong())

implicit def validDoubleValidate: Validate.Plain[String, ValidDouble] =
Validate.fromPartial(_.toDouble, "ValidDouble", ValidDouble())

implicit def validBigIntValidate: Validate.Plain[String, ValidBigInt] =
Validate.fromPartial(BigInt(_), "ValidBigInt", ValidBigInt())

implicit def validBigDecimalValidate: Validate.Plain[String, ValidBigDecimal] =
Validate.fromPartial(BigDecimal(_), "ValidBigDecimal", ValidBigDecimal())
}

private[refined] trait StringInference {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package eu.timepit.refined

import eu.timepit.refined.TestUtils._
import eu.timepit.refined.api.Validate
import eu.timepit.refined.string._
import org.scalacheck.{Arbitrary, Properties}
import org.scalacheck.Prop._
import org.scalacheck.Properties
import shapeless.Witness

class StringValidateSpec extends Properties("StringValidate") {
Expand Down Expand Up @@ -81,4 +82,23 @@ class StringValidateSpec extends Properties("StringValidate") {
property("IPv4.showResult.Failed") = secure {
showResult[IPv4]("::1") ?= "Predicate failed: ::1 is a valid IPv4."
}

private def validNumber[N: Arbitrary, P](name: String, invalidValue: String)(
implicit v: Validate[String, P]) = {
property(name) = secure {
forAll { (n: N) =>
isValid[P](n.toString) &&
(showResult[P](n.toString) ?= s"$name predicate passed.")
}
}
property(s"$name.showResult.Failed") = secure {
showResult[P](invalidValue).startsWith(s"$name predicate failed")
}
}

validNumber[Int, ValidInt]("ValidInt", Long.MaxValue.toString)
validNumber[Long, ValidLong]("ValidLong", "1.0")
validNumber[Double, ValidDouble]("ValidDouble", "a")
validNumber[BigInt, ValidBigInt]("ValidBigInt", "1.0")
validNumber[BigDecimal, ValidBigDecimal]("ValidBigDecimal", "a")
}

0 comments on commit 96897dc

Please sign in to comment.