Skip to content

Commit

Permalink
Fix transient field inconsitency in JSON codecs for records (#764)
Browse files Browse the repository at this point in the history
* Clean up test name

* Clean up test for decoding of case classes with transient field

* Add missing test for transient field annotation with default value implicitly available for the field type

* Clean up of tests

* Add support for transient fields with implicitly available schema default values in Schema.GenericRecord
  • Loading branch information
plokhotnyuk authored Jan 4, 2025
1 parent bb5dbed commit ffe4808
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,9 @@ object JsonCodec {
val spanWithDecoder =
(JsonError.ObjectAccess(fieldName), schemaDecoder(field.schema).asInstanceOf[ZJsonDecoder[Any]])
field.nameAndAliases.foreach(x => spansWithDecoders.put(x, spanWithDecoder))
if (field.optional && field.defaultValue.isDefined) defaults.put(fieldName, field.defaultValue.get)
if ((field.optional || field.transient) && field.defaultValue.isDefined) {
defaults.put(fieldName, field.defaultValue.get)
}
}
val rejectAdditionalFields = schema.annotations.exists(_.isInstanceOf[rejectExtraFields])
(trace: List[JsonError], in: RetractReader) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ object JsonCodecSpec extends ZIOSpecDefault {
charSequenceToByteChunk("""{"oneOf":{"_type":"StringValue2","value":"foo2"}}""")
)
},
test("case class") {
test("transient field annotation") {
assertEncodes(
searchRequestWithTransientFieldSchema,
SearchRequestWithTransientField("foo", 10, 20, "bar"),
Expand Down Expand Up @@ -431,7 +431,7 @@ object JsonCodecSpec extends ZIOSpecDefault {
suite("Generic Record")(
test("Do not encode transient field") {
assertEncodes(
RecordExample.schema.annotate(rejectExtraFields()),
RecordExample.schema,
RecordExample(f1 = Some("test"), f3 = Some("transient")),
charSequenceToByteChunk(
"""{"$f1":"test"}""".stripMargin
Expand Down Expand Up @@ -812,13 +812,31 @@ object JsonCodecSpec extends ZIOSpecDefault {
JsonError.Message("extra field") :: Nil
)
},
test("transient field annotation") {
test("transient field annotation with default value in class definition") {
assertDecodes(
searchRequestWithTransientFieldSchema,
SearchRequestWithTransientField("test", 0, 10, Schema[String].defaultValue.getOrElse("")),
SearchRequestWithTransientField("test", 0, 10),
charSequenceToByteChunk("""{"query":"test","pageNumber":0,"resultPerPage":10}""")
)
},
test("transient field annotation with default value implicitly available for the field type") {
case class CaseClassWithTransientField(transient: String)
assertDecodes(
Schema.CaseClass1[String, CaseClassWithTransientField](
id0 = TypeId.fromTypeName("SearchRequestWithTransientField"),
field0 = Schema.Field(
name0 = "transient",
schema0 = Schema[String],
get0 = _.transient,
set0 = (x, transient) => x.copy(transient = transient),
annotations0 = Chunk(new transientField())
),
defaultConstruct0 = new CaseClassWithTransientField(_)
),
CaseClassWithTransientField(Schema[String].defaultValue.toOption.get),
charSequenceToByteChunk("""{}""")
)
},
test("fieldDefaultValue") {
assertDecodes(
fieldDefaultValueSearchRequestSchema,
Expand Down Expand Up @@ -854,6 +872,13 @@ object JsonCodecSpec extends ZIOSpecDefault {
charSequenceToByteChunk("""{"foo":"s","bar":null}""")
)
},
test("with transient fields encoded as implicitly available schema default values") {
assertDecodes(
recordWithTransientSchema,
ListMap[String, Any]("foo" -> "", "bar" -> 0),
charSequenceToByteChunk("""{}""")
)
},
test("case class with option fields encoded as null") {
assertDecodes(
WithOptionFields.schema,
Expand Down Expand Up @@ -1991,7 +2016,7 @@ object JsonCodecSpec extends ZIOSpecDefault {
query: String,
pageNumber: Int,
resultPerPage: Int,
@transientField nextPage: String = ""
@transientField nextPage: String = "transient"
)

val searchRequestWithTransientFieldSchema: Schema[SearchRequestWithTransientField] =
Expand Down Expand Up @@ -2035,6 +2060,25 @@ object JsonCodecSpec extends ZIOSpecDefault {
)
)

val recordWithTransientSchema: Schema[ListMap[String, _]] = Schema.record(
TypeId.Structural,
Schema.Field(
"foo",
Schema.Primitive(StandardType.StringType),
annotations0 = Chunk(transientField()),
get0 = (p: ListMap[String, _]) => p("foo").asInstanceOf[String],
set0 = (p: ListMap[String, _], v: String) => p.updated("foo", v)
),
Schema
.Field(
"bar",
Schema.Primitive(StandardType.IntType),
annotations0 = Chunk(transientField()),
get0 = (p: ListMap[String, _]) => p("bar").asInstanceOf[Int],
set0 = (p: ListMap[String, _], v: Int) => p.updated("bar", v)
)
)

val nestedRecordSchema: Schema[ListMap[String, _]] = Schema.record(
TypeId.Structural,
Schema.Field(
Expand Down

0 comments on commit ffe4808

Please sign in to comment.