From cbc1cc7572d059e25bc3d9fc8bc6ab3d709adb24 Mon Sep 17 00:00:00 2001 From: Leigh Perry Date: Tue, 10 Dec 2019 12:28:24 +1100 Subject: [PATCH] Property based tests for Refined support (#144) * Property tests for numeric refined support * Distinguish test names * Format code * Fix 2.11 compilation --- .../config/refined/NumericSupportTest.scala | 142 ++++++++++++++++++ .../config/refined/StringSupportTest.scala | 2 +- 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 zio-config-refined/src/test/scala/zio/config/refined/NumericSupportTest.scala diff --git a/zio-config-refined/src/test/scala/zio/config/refined/NumericSupportTest.scala b/zio-config-refined/src/test/scala/zio/config/refined/NumericSupportTest.scala new file mode 100644 index 000000000..2cc43855a --- /dev/null +++ b/zio-config-refined/src/test/scala/zio/config/refined/NumericSupportTest.scala @@ -0,0 +1,142 @@ +package zio.config.refined + +import eu.timepit.refined.W +import eu.timepit.refined.api.Refined +import eu.timepit.refined.numeric.{ Divisible, Greater, GreaterEqual, Less, LessEqual, NonDivisible } +import zio.ZIO +import zio.config.ConfigDescriptor._ +import zio.config.{ helpers, read, write, BaseSpec, ConfigSource, ReadErrorsVector } +import zio.test.Assertion._ +import zio.test._ + +object NumericSupportTest + extends BaseSpec( + suite("Refined Numeric support")( + testM("Refined config Less roundtrip") { + checkM(Gen.int(1, 9).map(s => Refined.unsafeApply[Int, Less[W.`10`.T]](s))) { p => + val cfg = less[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config Less invalid") { + checkM(Gen.int(10, 100)) { p => + val cfg = less[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, Less[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + }, + testM("Refined config Greater roundtrip") { + checkM(Gen.int(11, 100).map(s => Refined.unsafeApply[Int, Greater[W.`10`.T]](s))) { p => + val cfg = greater[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config Greater invalid") { + checkM(Gen.int(1, 10)) { p => + val cfg = greater[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, Greater[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + }, + testM("Refined config LessEqual roundtrip") { + checkM(Gen.int(1, 10).map(s => Refined.unsafeApply[Int, LessEqual[W.`10`.T]](s))) { p => + val cfg = lessEqual[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config LessEqual invalid") { + checkM(Gen.int(11, 100)) { p => + val cfg = lessEqual[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, LessEqual[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + }, + testM("Refined config GreaterEqual roundtrip") { + checkM(Gen.int(10, 100).map(s => Refined.unsafeApply[Int, GreaterEqual[W.`10`.T]](s))) { p => + val cfg = greaterEqual[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config GreaterEqual invalid") { + checkM(Gen.int(1, 9)) { p => + val cfg = greaterEqual[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, GreaterEqual[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + }, + testM("Refined config Divisible roundtrip") { + checkM(Gen.int(1, 10).map(s => Refined.unsafeApply[Int, Divisible[W.`10`.T]](s * 10))) { p => + val cfg = divisible[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config Divisible invalid") { + checkM(Gen.int(1, 10).map(_ * 10 + 1)) { p => + val cfg = divisible[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, Divisible[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + }, + testM("Refined config NonDivisible roundtrip") { + checkM(Gen.int(1, 10).map(s => Refined.unsafeApply[Int, NonDivisible[W.`10`.T]](s * 10 + 1))) { p => + val cfg = nonDivisible[W.`10`.T](int("TEST")) + val p2 = + for { + written <- ZIO.fromEither(write(cfg, p)) + reread <- read(cfg from ConfigSource.fromPropertyTree(written)) + } yield reread + + assertM(p2, equalTo(p)) + } + }, + testM("Refined config NonDivisible invalid") { + checkM(Gen.int(1, 10).map(_ * 10)) { p => + val cfg = nonDivisible[W.`10`.T](int("TEST")) + val p2: ZIO[Any, ReadErrorsVector[String, String], Refined[Int, NonDivisible[W.`10`.T]]] = + read(cfg from ConfigSource.fromMap(Map("TEST" -> p.toString))) + + assertM(p2.either, helpers.assertErrors(_.size == 1)) + } + } + ) + ) diff --git a/zio-config-refined/src/test/scala/zio/config/refined/StringSupportTest.scala b/zio-config-refined/src/test/scala/zio/config/refined/StringSupportTest.scala index 8a945ecb8..92a038abe 100644 --- a/zio-config-refined/src/test/scala/zio/config/refined/StringSupportTest.scala +++ b/zio-config-refined/src/test/scala/zio/config/refined/StringSupportTest.scala @@ -31,7 +31,7 @@ import zio.test._ object StringSupportTest extends BaseSpec( - suite("Refined support")( + suite("Refined String support")( testM("Refined config EndsWith roundtrip") { checkM(genSymbol(0, 10).map(s => Refined.unsafeApply[String, EndsWith[W.`"abc"`.T]](s + "abc"))) { p => val cfg = endsWith[W.`"abc"`.T](string("TEST"))