Skip to content

Commit 0984c30

Browse files
Merge pull request #1339 from hkateu/refinevalidation
Code for SCALA-350
2 parents ed2aaa3 + 2379091 commit 0984c30

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

build.sbt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,14 @@ lazy val tapir = (project in file("scala-libraries-standalone/tapir"))
480480
scalaVersion := scala3Version
481481
)
482482

483+
lazy val refined = (project in file("scala-libraries-standalone/refined"))
484+
.settings(
485+
name := "refined",
486+
scalaVersion := scalaV,
487+
libraryDependencies += "eu.timepit" %% "refined" % "0.11.1",
488+
libraryDependencies ++= scalaTestDeps
489+
)
490+
483491
val spireVersion = "0.18.0"
484492
val kafkaVersion = "7.6.1-ce"
485493
val pureconfigVersion = "0.17.6"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.baeldung.refined
2+
3+
import eu.timepit.refined._
4+
import eu.timepit.refined.api.Refined
5+
import eu.timepit.refined.auto._
6+
import eu.timepit.refined.numeric._
7+
import eu.timepit.refined.string._
8+
import eu.timepit.refined.collection._
9+
import eu.timepit.refined.char._
10+
import eu.timepit.refined.boolean._
11+
import eu.timepit.refined.api.Validate
12+
13+
object RefinedIntro {
14+
// val oddNumber: Refined[Int, Odd] = 8
15+
// val oddNumber: Int Refined Odd = 8
16+
17+
val age: Int Refined Less[35] = 30
18+
val ageInterval: Int Refined Interval.Closed[30, 35] = 35
19+
val age2: Int Refined GreaterEqual[35] = 35
20+
val ageInput: Int = 36
21+
val ageCheck = refineV[GreaterEqual[35]](ageInput)
22+
23+
val myDigit: Char Refined Digit = '8'
24+
val myLetter: Char Refined Letter = 'H'
25+
26+
val myName: String Refined StartsWith["S"] = "Sandra"
27+
val myName2: String Refined EndsWith["t"] = "Herbert"
28+
// val myName3: String Refined StartsWith["s"] = "Sandra"
29+
// val myAddr: String Refined IPv6 = "127.0.0.1"
30+
31+
type myRegex = MatchesRegex["""[A-Za-z0-9]+"""]
32+
val accessCode: String Refined myRegex = "DC13h"
33+
34+
type myIntRegex = myRegex And ValidInt
35+
val accessCode2: String Refined myIntRegex = "97426"
36+
// val accessCode3: String Refined myIntRegex = "9742B"
37+
38+
val fruits = List("Banana", "Orange", "Lemon", "Guava")
39+
val contains = refineV[Contains["Berry"]](fruits)
40+
val forall = refineV[Forall[Trimmed]](fruits)
41+
val last = refineV[Last[Uuid]](fruits)
42+
val size = refineV[Size[Less[5]]](fruits)
43+
44+
case class Person(name: String, height: Double)
45+
case class Tall()
46+
case class Average()
47+
case class Short()
48+
49+
implicit val tallValidate: Validate.Plain[Person, Tall] =
50+
Validate.fromPredicate(
51+
p => p.height >= 6.0,
52+
p => s"(${p.name} is tall)",
53+
Tall()
54+
)
55+
56+
implicit val averageValidate: Validate.Plain[Person, Average] =
57+
Validate.fromPredicate(
58+
p => p.height >= 5.0 && p.height < 6.0,
59+
p => s"(${p.name} is average)",
60+
Average()
61+
)
62+
63+
implicit val shortValidate: Validate.Plain[Person, Short] =
64+
Validate.fromPredicate(
65+
p => p.height < 5.0,
66+
p => s"(${p.name} is short)",
67+
Short()
68+
)
69+
70+
val tall = refineV[Tall](Person("Herbert", 5.5))
71+
val average = refineV[Average](Person("Herbert", 5.5))
72+
}
73+
74+
object Hello extends App {
75+
import RefinedIntro._
76+
println(refineV[Short](Person("Herbert", 4.0)))
77+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.baeldung.refined
2+
3+
import org.scalatest.flatspec.AnyFlatSpec
4+
import org.scalatest.matchers.should.Matchers
5+
import eu.timepit.refined._
6+
import eu.timepit.refined.api.Refined
7+
import eu.timepit.refined.auto._
8+
import eu.timepit.refined.numeric._
9+
import eu.timepit.refined.string._
10+
import eu.timepit.refined.collection._
11+
import eu.timepit.refined.char._
12+
import eu.timepit.refined.boolean._
13+
import eu.timepit.refined.api.Validate
14+
import scala.util.{Right, Left}
15+
16+
class RefinedUnitTest extends AnyFlatSpec with Matchers {
17+
import RefinedIntro.{size => sizeTest, _}
18+
19+
"Int checks" should "pass with refined types" in {
20+
assert(refineV[Odd](8) == Left("Predicate (8 % 2 == 0) did not fail."))
21+
age shouldBe an[Int Refined Less[35]]
22+
ageInterval shouldBe an[Int Refined Interval.Closed[30, 35]]
23+
age2 shouldBe an[Int Refined GreaterEqual[35]]
24+
ageInput shouldBe an[Int]
25+
ageCheck shouldBe an[Either[String, Refined[Int, GreaterEqual[35]]]]
26+
}
27+
28+
"Char checks" should "pass for refined types" in {
29+
assert(myDigit.isInstanceOf[Char Refined Digit])
30+
assert(myLetter.isInstanceOf[Char Refined Letter])
31+
}
32+
33+
"String checks" should "pass for refined types" in {
34+
assert(
35+
refineV[StartsWith["s"]]("Sandra") == Left(
36+
"Predicate failed: \"Sandra\".startsWith(\"s\")."
37+
)
38+
)
39+
assert(
40+
refineV[IPv6]("127.0.0.1") == Left(
41+
"Predicate failed: 127.0.0.1 is a valid IPv6."
42+
)
43+
)
44+
assert(myName.isInstanceOf[String Refined StartsWith["S"]])
45+
assert(myName2.isInstanceOf[String Refined EndsWith["t"]])
46+
}
47+
48+
"Regex checks" should "pass for refined types" in {
49+
assert(
50+
refineV[myIntRegex]("9742B") == Left(
51+
"Right predicate of (\"9742B\".matches(\"[A-Za-z0-9]+\") && isValidValidInt(\"9742B\")) failed: ValidInt predicate failed: For input string: \"9742B\""
52+
)
53+
)
54+
assert(accessCode.isInstanceOf[String Refined myRegex])
55+
56+
assert(accessCode2.isInstanceOf[String Refined myIntRegex])
57+
}
58+
59+
"collection checks" should "pass for refined types" in {
60+
assert(
61+
forall
62+
.isInstanceOf[Either[String, Refined[List[String], Forall[Trimmed]]]]
63+
)
64+
assert(last.isInstanceOf[Either[String, Refined[List[String], Last[Uuid]]]])
65+
assert(
66+
sizeTest
67+
.isInstanceOf[Either[String, Refined[List[String], Size[Less[5]]]]]
68+
)
69+
}
70+
71+
"Person checks" should "pass for custom refined types" in {
72+
assert(tall.isInstanceOf[Either[String, Refined[Person, Tall]]])
73+
assert(average.isInstanceOf[Either[String, Refined[Person, Average]]])
74+
}
75+
}

0 commit comments

Comments
 (0)