package gs.predicate.v0.serde.json import gs.predicate.v0.api.Messages import gs.predicate.v0.json.JsonComparison import io.circe.Decoder import io.circe.Json import io.circe.syntax._ import java.time.LocalDate import munit.FunSuite class JsonComparisonCodecTests extends FunSuite: test("should fail to decode an unknown comparison") { val candidate = "unrecognized" val json: Json = Json.obj( JsonKeys.name -> Json.fromString(candidate) ) val decoded = Decoder[JsonComparison].decodeJson(json) assertEquals(decoded.isLeft, true) assertEquals( decoded.left.toOption.map(_.message), Some(Messages.unrecognizedJsonComparison(candidate)) ) } test("should serialize and deserialize comparison: Eq") { val target: Json = Json.obj("x" -> Json.fromString("y")) val jc = JsonComparison.Eq(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.Eq.Name)), (JsonKeys.value, target) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.Eq => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: Neq") { val target: Json = Json.obj("x" -> Json.fromString("y")) val jc = JsonComparison.Neq(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.Neq.Name)), (JsonKeys.value, target) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.Neq => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: StringContains") { val target = "target" val jc = JsonComparison.StringContains(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.StringContains.Name)), (JsonKeys.value, Json.fromString(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.StringContains => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: StringPrefix") { val target = "target" val jc = JsonComparison.StringPrefix(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.StringPrefix.Name)), (JsonKeys.value, Json.fromString(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.StringPrefix => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: StringSuffix") { val target = "target" val jc = JsonComparison.StringSuffix(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.StringSuffix.Name)), (JsonKeys.value, Json.fromString(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.StringSuffix => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: IntLessThan") { val target = 10 val jc = JsonComparison.IntLessThan(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.IntLessThan.Name)), (JsonKeys.value, Json.fromInt(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntLessThan => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: IntLessThanOrEqualTo") { val target = 10 val jc = JsonComparison.IntLessThanOrEqualTo(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.IntLessThanOrEqualTo.Name) ), (JsonKeys.value, Json.fromInt(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntLessThanOrEqualTo => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: IntGreaterThan") { val target = 10 val jc = JsonComparison.IntGreaterThan(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.IntGreaterThan.Name)), (JsonKeys.value, Json.fromInt(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntGreaterThan => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: IntGreaterThanOrEqualTo") { val target = 10 val jc = JsonComparison.IntGreaterThanOrEqualTo(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.IntGreaterThanOrEqualTo.Name) ), (JsonKeys.value, Json.fromInt(target)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntGreaterThanOrEqualTo => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: IntBetweenInclusive") { val lower = 1 val upper = 10 val jc = JsonComparison.IntBetweenInclusive(lower, upper) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.IntBetweenInclusive.Name) ), (JsonKeys.lower, Json.fromInt(lower)), (JsonKeys.upper, Json.fromInt(upper)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntBetweenInclusive => d.lower -> d.upper case _ => fail("Parsed an unexpected JsonComparison.") }, Right(lower -> upper) ) } test("should serialize and deserialize comparison: IntBetweenExclusive") { val lower = 1 val upper = 10 val jc = JsonComparison.IntBetweenExclusive(lower, upper) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.IntBetweenExclusive.Name) ), (JsonKeys.lower, Json.fromInt(lower)), (JsonKeys.upper, Json.fromInt(upper)) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.IntBetweenExclusive => d.lower -> d.upper case _ => fail("Parsed an unexpected JsonComparison.") }, Right(lower -> upper) ) } test("should serialize and deserialize comparison: DateEq") { val target = LocalDate.now() val jc = JsonComparison.DateEq(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.DateEq.Name)), (JsonKeys.value, Json.fromString(target.toString())) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.DateEq => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: DateBefore") { val target = LocalDate.now() val jc = JsonComparison.DateBefore(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.DateBefore.Name)), (JsonKeys.value, Json.fromString(target.toString())) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.DateBefore => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: DateAfter") { val target = LocalDate.now() val jc = JsonComparison.DateAfter(target) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( (JsonKeys.name, Json.fromString(JsonComparison.DateAfter.Name)), (JsonKeys.value, Json.fromString(target.toString())) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.DateAfter => d.target case _ => fail("Parsed an unexpected JsonComparison.") }, Right(target) ) } test("should serialize and deserialize comparison: DateBetweenInclusive") { val lower = LocalDate.now().minusDays(1L) val upper = LocalDate.now().plusDays(1L) val jc = JsonComparison.DateBetweenInclusive(lower, upper) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.DateBetweenInclusive.Name) ), (JsonKeys.lower, Json.fromString(lower.toString())), (JsonKeys.upper, Json.fromString(upper.toString())) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.DateBetweenInclusive => d.lower -> d.upper case _ => fail("Parsed an unexpected JsonComparison.") }, Right(lower -> upper) ) } test("should serialize and deserialize comparison: DateBetweenExclusive") { val lower = LocalDate.now().minusDays(1L) val upper = LocalDate.now().plusDays(1L) val jc = JsonComparison.DateBetweenExclusive(lower, upper) val encoded = jc.asJson val decoded = Decoder[JsonComparison].decodeJson(encoded) assertEquals( encoded, Json.obj( ( JsonKeys.name, Json.fromString(JsonComparison.DateBetweenExclusive.Name) ), (JsonKeys.lower, Json.fromString(lower.toString())), (JsonKeys.upper, Json.fromString(upper.toString())) ) ) assertEquals(decoded.isRight, true) assertEquals( decoded.map { case d: JsonComparison.DateBetweenExclusive => d.lower -> d.upper case _ => fail("Parsed an unexpected JsonComparison.") }, Right(lower -> upper) ) }