-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ee93855
commit c4aeef4
Showing
9 changed files
with
157 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 12 additions & 20 deletions
32
circe/src/test/scala/me/wojnowski/scuid/circe/CodecsTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,61 @@ | ||
package me.wojnowski.scuid.circe | ||
|
||
import io.circe.syntax.* | ||
import me.wojnowski.scuid.Cuid2 | ||
import me.wojnowski.scuid.Cuid2Custom | ||
import me.wojnowski.scuid.Cuid2Long | ||
import munit.ScalaCheckSuite | ||
import me.wojnowski.scuid.Generators | ||
|
||
import org.scalacheck.Gen | ||
import org.scalacheck.Prop.forAll | ||
import org.scalacheck.Test | ||
|
||
class CodecsTest extends ScalaCheckSuite { | ||
import io.circe.syntax.* | ||
import munit.ScalaCheckSuite | ||
|
||
class CodecsTest extends ScalaCheckSuite with Generators { | ||
override protected def scalaCheckTestParameters: Test.Parameters = | ||
super.scalaCheckTestParameters.withMinSuccessfulTests(200) | ||
|
||
test("Cuid2 encoding/decoding (success)") { | ||
forAll(cuid2Gen(24)) { rawCuid2 => | ||
forAll(validRawCuidGen(24)) { rawCuid2 => | ||
val cuid2 = Cuid2.validate(rawCuid2).get | ||
assertEquals(cuid2.asJson, rawCuid2.asJson) | ||
assertEquals(rawCuid2.asJson.as[Cuid2], Right(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2 decoding (failure)") { | ||
forAll(cuid2GenRandomLengthButNot(24)) { rawInvalidCuid2 => | ||
forAll(validRawCuid2GenRandomLengthButNot(24)) { rawInvalidCuid2 => | ||
assert(rawInvalidCuid2.asJson.as[Cuid2].isLeft) | ||
} | ||
} | ||
|
||
test("Cuid2Long encoding/decoding (success)") { | ||
forAll(cuid2Gen(32)) { rawCuid2 => | ||
forAll(validRawCuidGen(32)) { rawCuid2 => | ||
val cuid2 = Cuid2Long.validate(rawCuid2).get | ||
assertEquals(cuid2.asJson, rawCuid2.asJson) | ||
assertEquals(rawCuid2.asJson.as[Cuid2Long], Right(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2Long decoding (failure)") { | ||
forAll(cuid2GenRandomLengthButNot(32)) { rawInvalidCuid2 => | ||
forAll(validRawCuid2GenRandomLengthButNot(32)) { rawInvalidCuid2 => | ||
assert(rawInvalidCuid2.asJson.as[Cuid2Long].isLeft) | ||
} | ||
} | ||
|
||
test("Cuid2Custom encoding/decoding (success)") { | ||
forAll(cuid2Gen(27)) { rawCuid2 => | ||
forAll(validRawCuidGen(27)) { rawCuid2 => | ||
val cuid2 = Cuid2Custom.validate[27](rawCuid2).get | ||
assertEquals(cuid2.asJson, rawCuid2.asJson) | ||
assertEquals(rawCuid2.asJson.as[Cuid2Custom[27]], Right(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2Custom decoding (failure)") { | ||
forAll(cuid2GenRandomLengthButNot(27)) { rawInvalidCuid2 => | ||
forAll(validRawCuid2GenRandomLengthButNot(27)) { rawInvalidCuid2 => | ||
assert(rawInvalidCuid2.asJson.as[Cuid2Custom[27]].isLeft) | ||
} | ||
} | ||
|
||
private def cuid2Gen(length: Int): Gen[String] = | ||
for { | ||
prefix <- Gen.alphaLowerChar | ||
suffix <- Gen.stringOfN(length - 1, Gen.oneOf(Gen.alphaLowerChar, Gen.numChar)) | ||
} yield s"$prefix$suffix" | ||
|
||
private def cuid2GenRandomLengthButNot(length: Int): Gen[String] = | ||
Gen.chooseNum(4, 36).retryUntil(_ != length).flatMap { length => | ||
cuid2Gen(length) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package me.wojnowski.scuid | ||
|
||
import org.scalacheck.Gen | ||
|
||
trait Generators { | ||
private val printableChars = 32.toChar to 126.toChar | ||
|
||
val lowercaseGen: Gen[Char] = Gen.alphaLowerChar | ||
|
||
val nonLowercaseGen: Gen[Char] = Gen.oneOf(printableChars.filterNot(_.isLower)) | ||
|
||
val lowercaseAlphanumGen: Gen[Char] = Gen.oneOf(lowercaseGen, Gen.numChar) | ||
|
||
val nonLowercaseAlphanumGen: Gen[Char] = Gen.oneOf(printableChars.filterNot(_.isLower).filterNot(_.isDigit)) | ||
|
||
def validRawCuidGen(length: Int): Gen[String] = rawCuidLikeGen(lowercaseGen, lowercaseAlphanumGen, length) | ||
|
||
def rawCuidLikeGen(firstChar: Gen[Char], otherChars: Gen[Char], length: Int): Gen[String] = | ||
for { | ||
firstLetter <- firstChar | ||
otherChars <- Gen.stringOfN(length - 1, otherChars) | ||
} yield s"$firstLetter$otherChars" | ||
|
||
def validRawCuid2GenRandomLengthButNot(length: Int): Gen[String] = | ||
Gen.chooseNum(4, 36).retryUntil(_ != length).flatMap { length => | ||
validRawCuidGen(length) | ||
} | ||
|
||
} |
27 changes: 27 additions & 0 deletions
27
tapir/src/main/scala/me/wojnowski/scuid/tapir/TapirCodec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package me.wojnowski.scuid.tapir | ||
|
||
import me.wojnowski.scuid.Cuid2 | ||
import me.wojnowski.scuid.Cuid2Custom | ||
import me.wojnowski.scuid.Cuid2Long | ||
|
||
import sttp.tapir.Codec | ||
import sttp.tapir.Codec.PlainCodec | ||
import sttp.tapir.Schema | ||
|
||
trait TapirCodec { | ||
implicit val schemaForCuid2: Schema[Cuid2] = Schema.string.format("Cuid2 (length 24)") | ||
|
||
implicit val codecForCuid2: PlainCodec[Cuid2] = | ||
Codec.string.mapEither(Cuid2.validate(_).toRight("Invalid Cuid2 (length 24)"))(_.render) | ||
|
||
implicit val schemaForCuid2Long: Schema[Cuid2Long] = Schema.string.format("Cuid2 (length 24)") | ||
|
||
implicit val codecForCuid2Long: PlainCodec[Cuid2Long] = | ||
Codec.string.mapEither(Cuid2Long.validate(_).toRight("Invalid Cuid2 (length 24)"))(_.render) | ||
|
||
implicit def schemaForCuid2Custom[L <: Int](implicit L: ValueOf[L]): Schema[Cuid2Custom[L]] = | ||
Schema.string.format(s"Cuid2 (length ${L.value})") | ||
|
||
implicit def codecForCuid2Custom[L <: Int](implicit L: ValueOf[L]): PlainCodec[Cuid2Custom[L]] = | ||
Codec.string.mapEither(Cuid2Custom.validate[L](_).toRight(s"Invalid Cuid2 (length ${L.value})"))(_.render) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package me.wojnowski.scuid | ||
|
||
package object tapir extends TapirCodec |
61 changes: 61 additions & 0 deletions
61
tapir/src/test/scala/me/wojnowski/scuid/tapir/TapirCodecTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package me.wojnowski.scuid.tapir | ||
|
||
import me.wojnowski.scuid.Cuid2 | ||
import me.wojnowski.scuid.Cuid2Custom | ||
import me.wojnowski.scuid.Cuid2Long | ||
import me.wojnowski.scuid.Generators | ||
|
||
import org.scalacheck.Prop.forAll | ||
import org.scalacheck.Test | ||
|
||
import munit.ScalaCheckSuite | ||
import sttp.tapir.DecodeResult | ||
|
||
class TapirCodecTest extends ScalaCheckSuite with Generators { | ||
override protected def scalaCheckTestParameters: Test.Parameters = | ||
super.scalaCheckTestParameters.withMinSuccessfulTests(200) | ||
|
||
test("Cuid2 encoding/decoding (success)") { | ||
forAll(validRawCuidGen(24)) { rawCuid2 => | ||
val cuid2 = Cuid2.validate(rawCuid2).get | ||
|
||
assertEquals(codecForCuid2.encode(cuid2), rawCuid2) | ||
assertEquals(codecForCuid2.decode(rawCuid2), DecodeResult.Value(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2 decoding (failure)") { | ||
forAll(validRawCuid2GenRandomLengthButNot(24)) { rawInvalidCuid2 => | ||
assert(codecForCuid2.decode(rawInvalidCuid2).isInstanceOf[DecodeResult.Failure]) | ||
} | ||
} | ||
|
||
test("Cuid2Long encoding/decoding (success)") { | ||
forAll(validRawCuidGen(32)) { rawCuid2 => | ||
val cuid2 = Cuid2Long.validate(rawCuid2).get | ||
assertEquals(codecForCuid2Long.encode(cuid2), rawCuid2) | ||
assertEquals(codecForCuid2Long.decode(rawCuid2), DecodeResult.Value(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2Long decoding (failure)") { | ||
forAll(validRawCuid2GenRandomLengthButNot(32)) { rawInvalidCuid2 => | ||
assert(codecForCuid2.decode(rawInvalidCuid2).isInstanceOf[DecodeResult.Failure]) | ||
} | ||
} | ||
|
||
test("Cuid2Custom encoding/decoding (success)") { | ||
forAll(validRawCuidGen(27)) { rawCuid2 => | ||
val cuid2 = Cuid2Custom.validate[27](rawCuid2).get | ||
assertEquals(codecForCuid2Custom[27].encode(cuid2), rawCuid2) | ||
assertEquals(codecForCuid2Custom[27].decode(rawCuid2), DecodeResult.Value(cuid2)) | ||
} | ||
} | ||
|
||
test("Cuid2Custom decoding (failure)") { | ||
forAll(validRawCuid2GenRandomLengthButNot(27)) { rawInvalidCuid2 => | ||
assert(codecForCuid2Custom[27].decode(rawInvalidCuid2).isInstanceOf[DecodeResult.Failure]) | ||
} | ||
} | ||
|
||
} |