Skip to content

Commit

Permalink
Close #286 - [refined4s-doobie] Add doobie support for NonBlankString
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin-lee committed Apr 7, 2024
1 parent bcdfdb2 commit 09fb334
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ trait all {
inline given derivedNonEmptyStringGet(using Show[String]): Get[NonEmptyString] = Get[String].temap(NonEmptyString.from)
inline given derivedNonEmptyStringPut: Put[NonEmptyString] = Put[String].contramap(_.value)

inline given derivedNonBlankStringGet(using Show[String]): Get[NonBlankString] = Get[String].temap(NonBlankString.from)
inline given derivedNonBlankStringPut: Put[NonBlankString] = Put[String].contramap(_.value)

inline given derivedUuidGet(using Show[String]): Get[Uuid] = Get[String].temap(Uuid.from)
inline given derivedUuidPut: Put[Uuid] = Put[String].contramap(_.value)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package refined4s.modules.doobie.derivation.types

import cats.effect.ContextShift
import cats.syntax.all.*
import hedgehog.*
import hedgehog.runner.*
import doobie.{Get, Put}
import doobie.syntax.all.*
import doobie.{Get, Put}
import extras.core.syntax.all.*
import extras.doobie.RunWithDb
import extras.doobie.ce2.DbTools
import extras.runner.ce2.RunSyncCe2
import hedgehog.*
import hedgehog.runner.*
import refined4s.*
import refined4s.modules.doobie.derivation.types.all.given
import refined4s.types.all.*
import refined4s.types.networkGens
import refined4s.modules.doobie.derivation.types.all.given

import java.util.UUID
import java.util.concurrent.atomic.AtomicInteger
Expand Down Expand Up @@ -103,6 +104,8 @@ object allSpec extends Properties, RunSyncCe2, RunWithDb {
//
propertyWithDb("test Get[NonEmptyString] and Put[NonEmptyString]", postgresPortNumber.getAndIncrement(), testGetAndPutNonEmptyString),
//
propertyWithDb("test Get[NonBlankString] and Put[NonBlankString]", postgresPortNumber.getAndIncrement(), testGetAndPutNonBlankString),
//
propertyWithDb("test Get[Uuid] and Put[Uuid]", postgresPortNumber.getAndIncrement(), testGetAndPutUuid),
//
propertyWithDb("test Get[Uri] and Put[Uri]", postgresPortNumber.getAndIncrement(), testGetAndPutUri),
Expand Down Expand Up @@ -1815,6 +1818,77 @@ object allSpec extends Properties, RunSyncCe2, RunWithDb {

///

def testGetAndPutNonBlankString(testName: String, postgresPortNumber: Int): Property =
for {
nonWhitespaceString <- Gen
.string(hedgehog.extra.Gens.genNonWhitespaceChar, Range.linear(1, 10))
.map(s => if s === "\u0000" then "blah" else s)
.log("nonWhitespaceString")
whitespaceString <- Gen
.string(
hedgehog.extra.Gens.genCharByRange(refined4s.types.strings.WhitespaceCharRange),
Range.linear(1, 10),
)
.log("whitespaceString")

s <- Gen.constant(scala.util.Random.shuffle((nonWhitespaceString + whitespaceString).toList).mkString).log("s")
} yield withDb[F](
testName,
postgresPortNumber,
sql"""CREATE SCHEMA IF NOT EXISTS db_tools_test""",
sql"""
CREATE TABLE IF NOT EXISTS db_tools_test.example
(
id SERIAL PRIMARY KEY,
value TEXT NOT NULL
)
""",
) { transactor =>

val expected = NonBlankString.unsafeFrom(s)

val expectedFetchBefore = none[NonBlankString]
val expectedInsert = 1
val expectedFetchAfter = expected.some

val fetch = DbTools.fetchSingleRow[F][NonBlankString](
sql"""
SELECT value
FROM db_tools_test.example
"""
)(transactor)

val insert = DbTools.updateSingle[F](
sql"""
INSERT INTO db_tools_test.example (value) VALUES ($expected)
"""
)(transactor)

for {
fetchResultBefore <- fetch.map(_ ==== expectedFetchBefore)
insertResult <- insert.map(_ ==== expectedInsert)
fetchResultAfter <- fetch.map(actual =>
(actual ==== expectedFetchAfter).log(
show""" actual: ${actual.map(_.value)}
|expectedFetchAfter: ${expectedFetchAfter.map(_.value)}
|
| actual (unicode): ${actual.map(_.value.encodeToUnicode)}
|expectedFetchAfter (unicode): ${expectedFetchAfter.map(_.value.encodeToUnicode)}
|""".stripMargin
)
)
} yield Result.all(
List(
fetchResultBefore.log("Failed: fetch before"),
insertResult.log("Failed: insert"),
fetchResultAfter.log("Failed: fetch after"),
)
)

}

///

def testGetAndPutUuid(testName: String, postgresPortNumber: Int): Property =
for {
uuid <- Gen.constant(UUID.randomUUID()).log("uuid")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ trait all {
inline given derivedNonEmptyStringGet(using Show[String]): Get[NonEmptyString] = Get[String].temap(NonEmptyString.from)
inline given derivedNonEmptyStringPut: Put[NonEmptyString] = Put[String].contramap(_.value)

inline given derivedNonBlankStringGet(using Show[String]): Get[NonBlankString] = Get[String].temap(NonBlankString.from)
inline given derivedNonBlankStringPut: Put[NonBlankString] = Put[String].contramap(_.value)

inline given derivedUuidGet(using Show[String]): Get[Uuid] = Get[String].temap(Uuid.from)
inline given derivedUuidPut: Put[Uuid] = Put[String].contramap(_.value)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.effect.IO
import cats.syntax.all.*
import doobie.syntax.all.*
import doobie.{Get, Put}
import extras.core.syntax.all.*
import extras.doobie.RunWithDb
import extras.doobie.ce3.DbTools
import extras.hedgehog.ce3.CatsEffectRunner
Expand Down Expand Up @@ -104,6 +105,8 @@ object allSpec extends Properties, CatsEffectRunner, RunWithDb {
//
propertyWithDb("test Get[NonEmptyString] and Put[NonEmptyString]", postgresPortNumber.getAndIncrement(), testGetAndPutNonEmptyString),
//
propertyWithDb("test Get[NonBlankString] and Put[NonBlankString]", postgresPortNumber.getAndIncrement(), testGetAndPutNonBlankString),
//
propertyWithDb("test Get[Uuid] and Put[Uuid]", postgresPortNumber.getAndIncrement(), testGetAndPutUuid),
//
propertyWithDb("test Get[Uri] and Put[Uri]", postgresPortNumber.getAndIncrement(), testGetAndPutUri),
Expand Down Expand Up @@ -1882,6 +1885,79 @@ object allSpec extends Properties, CatsEffectRunner, RunWithDb {

///

def testGetAndPutNonBlankString(testName: String, postgresPortNumber: Int): Property =
for {
nonWhitespaceString <- Gen
.string(hedgehog.extra.Gens.genNonWhitespaceChar, Range.linear(1, 10))
.map(s => if s === "\u0000" then "blah" else s)
.log("nonWhitespaceString")
whitespaceString <- Gen
.string(
hedgehog.extra.Gens.genCharByRange(refined4s.types.strings.WhitespaceCharRange),
Range.linear(1, 10),
)
.log("whitespaceString")

s <- Gen.constant(scala.util.Random.shuffle((nonWhitespaceString + whitespaceString).toList).mkString).log("s")
} yield runIO(
withDb[F](
testName,
postgresPortNumber,
sql"""CREATE SCHEMA IF NOT EXISTS db_tools_test""",
sql"""
CREATE TABLE IF NOT EXISTS db_tools_test.example
(
id SERIAL PRIMARY KEY,
value TEXT NOT NULL
)
""",
) { transactor =>

val expected = NonBlankString.unsafeFrom(s)

val expectedFetchBefore = none[NonBlankString]
val expectedInsert = 1
val expectedFetchAfter = expected.some

val fetch = DbTools.fetchSingleRow[F][NonBlankString](
sql"""
SELECT value
FROM db_tools_test.example
"""
)(transactor)

val insert = DbTools.updateSingle[F](
sql"""
INSERT INTO db_tools_test.example (value) VALUES ($expected)
"""
)(transactor)

for {
fetchResultBefore <- fetch.map(_ ==== expectedFetchBefore)
insertResult <- insert.map(_ ==== expectedInsert)
fetchResultAfter <- fetch.map(actual =>
(actual ==== expectedFetchAfter).log(
show""" actual: ${actual.map(_.value)}
|expectedFetchAfter: ${expectedFetchAfter.map(_.value)}
|
| actual (unicode): ${actual.map(_.value.encodeToUnicode)}
|expectedFetchAfter (unicode): ${expectedFetchAfter.map(_.value.encodeToUnicode)}
|""".stripMargin
)
)
} yield Result.all(
List(
fetchResultBefore.log("Failed: fetch before"),
insertResult.log("Failed: insert"),
fetchResultAfter.log("Failed: fetch after"),
)
)

}
)

///

def testGetAndPutUuid(testName: String, postgresPortNumber: Int): Property =
for {
uuid <- Gen.constant(UUID.randomUUID()).log("uuid")
Expand Down

0 comments on commit 09fb334

Please sign in to comment.