Skip to content

Commit

Permalink
Merge pull request #984 from markus1189/validated-ensure
Browse files Browse the repository at this point in the history
Add Validated.ensure
  • Loading branch information
stew committed May 9, 2016
2 parents 40a1211 + e3eb1d0 commit 19d0de0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
14 changes: 14 additions & 0 deletions core/src/main/scala/cats/data/Validated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable {
case Valid(a) => Invalid(a)
case Invalid(e) => Valid(e)
}

/**
* Ensure that a successful result passes the given predicate,
* falling back to an Invalid of `onFailure` if the predicate
* returns false.
*
* For example:
* {{{
* scala> Validated.valid("").ensure(new IllegalArgumentException("Must not be empty"))(_.nonEmpty)
* res0: Validated[IllegalArgumentException,String] = Invalid(java.lang.IllegalArgumentException: Must not be empty)
* }}}
*/
def ensure[EE >: E](onFailure: => EE)(f: A => Boolean): Validated[EE, A] =
fold(_ => this, a => if (f(a)) this else Validated.invalid(onFailure))
}

object Validated extends ValidatedInstances with ValidatedFunctions{
Expand Down
16 changes: 16 additions & 0 deletions tests/src/test/scala/cats/tests/ValidatedTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,20 @@ class ValidatedTests extends CatsSuite {
val z = x.map2(y)((i, b) => if (b) i + 1 else i)
z should === (NonEmptyList("error 1", "error 2").invalid[Int])
}

test("ensure on Invalid is identity") {
forAll { (x: Validated[Int,String], i: Int, p: String => Boolean) =>
if (x.isInvalid) {
x.ensure(i)(p) should === (x)
}
}
}

test("ensure should fail if predicate not satisfied") {
forAll { (x: Validated[String, Int], s: String, p: Int => Boolean) =>
if (x.exists(!p(_))) {
x.ensure(s)(p) should === (Validated.invalid(s))
}
}
}
}

0 comments on commit 19d0de0

Please sign in to comment.