Skip to content

Commit 211aa24

Browse files
committed
ZIO test integration.
1 parent 270955b commit 211aa24

File tree

4 files changed

+151
-1
lines changed

4 files changed

+151
-1
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,24 @@ class MyTest {
154154
}
155155
}
156156
```
157+
158+
## ZIO test
159+
Include the following dependency into your project:
160+
161+
```groovy
162+
testImplementation "com.github.simy4.coregex:coregex-zio-test"
163+
```
164+
165+
Use the provided `CoregexGen` class to generate a string that would match the regular expression predicate:
166+
167+
```scala
168+
object MySpec extends ZIOSpecDefault {
169+
def spec = suite("my spec")(
170+
test("my property") {
171+
check(CoregexGen.from(Pattern.compile("[a-zA-Z]{3}"))) { str =>
172+
assertTrue(str.length == 3)
173+
}
174+
}
175+
)
176+
}
177+
```

build.sbt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ lazy val root = (project in file("."))
5555
name := "coregex-parent",
5656
publish / skip := true
5757
)
58-
.aggregate(core, functionaljavaQuickcheck, jqwik, junitQuickcheck, kotest, scalacheck, vavrTest)
58+
.aggregate(core, functionaljavaQuickcheck, jqwik, junitQuickcheck, kotest, scalacheck, vavrTest, zioTest)
5959

6060
lazy val core = (project in file("core"))
6161
.settings(
@@ -171,5 +171,20 @@ lazy val vavrTest = (project in file("vavr-test"))
171171
.settings(jacocoSettings)
172172
.dependsOn(core)
173173

174+
lazy val zioTest = (project in file("zio-test"))
175+
.settings(
176+
name := "zio-test",
177+
moduleName := "coregex-zio-test",
178+
description := "zio-test bindings for coregex library.",
179+
headerEndYear := Some(2025),
180+
libraryDependencies ++= Seq(
181+
"dev.zio" %% "zio-test" % "2.1.21" % Provided,
182+
"dev.zio" %% "zio-test-sbt" % "2.1.21" % Test
183+
),
184+
crossScalaVersions := supportedScalaVersions
185+
)
186+
.settings(jacocoSettings)
187+
.dependsOn(core)
188+
174189
addCommandAlias("build", ";javafmtCheckAll;scalafmtCheckAll;headerCheck;jacoco")
175190
addCommandAlias("fmt", ";javafmtAll;scalafmtAll;scalafmtSbt;headerCreate")
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2021-2025 Alex Simkin
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.github.simy4.coregex
18+
package scalacheck
19+
20+
import core.Coregex
21+
import zio.Trace
22+
import zio.stream.ZStream
23+
import zio.test.{ Gen, Sample }
24+
25+
import java.util.regex.Pattern
26+
import scala.util.matching.Regex
27+
28+
object CoregexGen {
29+
def fromRegex(regex: Regex)(implicit trace: Trace): Gen[Any, String] = fromPattern(regex.pattern)
30+
31+
def fromPattern(regex: Pattern)(implicit trace: Trace): Gen[Any, String] = apply(Coregex.from(regex))
32+
33+
def apply(coregex: Coregex)(implicit trace: Trace): Gen[Any, String] =
34+
Gen.long.flatMap { seed =>
35+
Gen.const(coregex.generate(seed)).reshrink(Sample(_, shrink(coregex, seed)))
36+
}
37+
38+
private def shrink(coregex: Coregex, seed: Long): ZStream[Any, Nothing, Sample[Any, String]] =
39+
ZStream
40+
.fromJavaIterator(coregex.shrink().iterator())
41+
.orDie
42+
.map(coregex => Sample(coregex.generate(seed), shrink(coregex, seed)))
43+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2021-2025 Alex Simkin
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.github.simy4.coregex.scalacheck
18+
19+
import zio.Scope
20+
import zio.test._
21+
22+
import java.net.InetAddress
23+
import java.time.format.DateTimeFormatter
24+
import java.util.UUID
25+
import java.util.regex.Pattern
26+
27+
object CoregexSpec extends ZIOSpecDefault {
28+
def spec: Spec[TestEnvironment with Scope, Any] = suite("Coregex")(
29+
test("should generate matching UUID string") {
30+
check(
31+
CoregexGen.fromPattern(
32+
Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
33+
)
34+
) { uuid =>
35+
assertTrue(uuid == UUID.fromString(uuid).toString)
36+
}
37+
},
38+
test("should generate matching IPv4 string") {
39+
check(
40+
CoregexGen.fromPattern(
41+
Pattern.compile("((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])")
42+
)
43+
) { ipv4 =>
44+
ipv4
45+
.split('.')
46+
.zip(InetAddress.getByName(ipv4).getHostAddress.split('.'))
47+
.map { case (expected, actual) => assertTrue(expected.toInt == actual.toInt) }
48+
.reduce(_ && _)
49+
}
50+
},
51+
test("should generate matching ISO-8601 date string") {
52+
check(
53+
CoregexGen.fromPattern(
54+
Pattern.compile(
55+
"[12]\\d{3}-(?:0[1-9]|1[012])-(?:0[1-9]|1\\d|2[0-8])T(?:1\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{2}[1-9])?Z"
56+
)
57+
)
58+
) { iso8601Date =>
59+
val formatter = DateTimeFormatter.ISO_INSTANT
60+
assertTrue(iso8601Date == formatter.format(formatter.parse(iso8601Date)))
61+
}
62+
},
63+
test("should generate unique strings") {
64+
check(Gen.listOf(CoregexGen.fromPattern(Pattern.compile("[a-zA-Z0-9]{32,}")))) { strings =>
65+
assertTrue(strings.forall { s =>
66+
s.length >= 32 && s.forall(_.isLetterOrDigit)
67+
}) && assertTrue(strings.size == strings.toSet.size)
68+
}
69+
}
70+
)
71+
}

0 commit comments

Comments
 (0)