-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: ignore __type when deserializing union for AWS Json protocols #964
Changes from 2 commits
3c7febc
febc8da
c2cfdbb
c207a32
5769b44
5258f30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -198,7 +198,13 @@ private class JsonFieldIterator( | |
val token = reader.nextTokenOf<JsonToken.Name>() | ||
val propertyName = token.value | ||
val field = descriptor.fields.find { it.serialName == propertyName } | ||
field?.index ?: Deserializer.FieldIterator.UNKNOWN_FIELD | ||
|
||
if (descriptor.traits.contains(IgnoreKey(propertyName))) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style: Consider |
||
reader.skipNext() // the value of the ignored key | ||
return findNextFieldIndex() | ||
} else { | ||
field?.index ?: Deserializer.FieldIterator.UNKNOWN_FIELD | ||
} | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package aws.smithy.kotlin.runtime.serde.json | ||
|
||
import aws.smithy.kotlin.runtime.serde.SdkFieldDescriptor | ||
import aws.smithy.kotlin.runtime.serde.SdkObjectDescriptor | ||
import aws.smithy.kotlin.runtime.serde.SerialKind | ||
import aws.smithy.kotlin.runtime.serde.deserializeStruct | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
|
||
class JsonDeserializerIgnoresKeysTest { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Every test has explicitly modeled field descriptors. You're missing coverage for unmodeled fields that we want to skip rather than enumerate as unknown. |
||
class IgnoresKeysTest { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this double-nested class seems unnecessary, I think you can just declare these at the top-level without using a |
||
companion object { | ||
val X_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("x")) | ||
val Y_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("y")) | ||
val Z_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("z")) | ||
val OBJ_DESCRIPTOR = SdkObjectDescriptor.build { | ||
trait(IgnoreKey("z")) // <---- | ||
field(X_DESCRIPTOR) | ||
field(Y_DESCRIPTOR) | ||
field(Z_DESCRIPTOR) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun itIgnoresKeys() { | ||
val payload = """ | ||
{ | ||
"x": 1, | ||
"y": 2, | ||
"z": 3 | ||
} | ||
""".trimIndent().encodeToByteArray() | ||
|
||
val deserializer = JsonDeserializer(payload) | ||
var x: Int? = null | ||
var y: Int? = null | ||
var z: Int? = null | ||
deserializer.deserializeStruct(IgnoresKeysTest.OBJ_DESCRIPTOR) { | ||
loop@ while (true) { | ||
when (findNextFieldIndex()) { | ||
IgnoresKeysTest.X_DESCRIPTOR.index -> x = deserializeInt() | ||
IgnoresKeysTest.Y_DESCRIPTOR.index -> y = deserializeInt() | ||
IgnoresKeysTest.Z_DESCRIPTOR.index -> z = deserializeInt() | ||
null -> break@loop | ||
} | ||
} | ||
} | ||
|
||
assertEquals(1, x) | ||
assertEquals(2, y) | ||
assertEquals(null, z) | ||
} | ||
|
||
@Test | ||
fun itIgnoresKeysOutOfOrder() { | ||
val payload = """ | ||
{ | ||
"z": 3, | ||
"x": 1, | ||
"y": 2 | ||
} | ||
""".trimIndent().encodeToByteArray() | ||
|
||
val deserializer = JsonDeserializer(payload) | ||
var x: Int? = null | ||
var y: Int? = null | ||
var z: Int? = null | ||
deserializer.deserializeStruct(IgnoresKeysTest.OBJ_DESCRIPTOR) { | ||
loop@ while (true) { | ||
when (findNextFieldIndex()) { | ||
IgnoresKeysTest.X_DESCRIPTOR.index -> x = deserializeInt() | ||
IgnoresKeysTest.Y_DESCRIPTOR.index -> y = deserializeInt() | ||
IgnoresKeysTest.Z_DESCRIPTOR.index -> z = deserializeInt() | ||
null -> break@loop | ||
} | ||
} | ||
} | ||
|
||
assertEquals(1, x) | ||
assertEquals(2, y) | ||
assertEquals(null, z) | ||
} | ||
|
||
@Test | ||
fun itIgnoresKeysManyTimes() { | ||
val payload = """ | ||
{ | ||
"x": 1, | ||
"y": 2, | ||
"z": 3, | ||
"z": 3, | ||
"z": 3 | ||
} | ||
""".trimIndent().encodeToByteArray() | ||
|
||
val deserializer = JsonDeserializer(payload) | ||
var x: Int? = null | ||
var y: Int? = null | ||
var z: Int? = null | ||
deserializer.deserializeStruct(IgnoresKeysTest.OBJ_DESCRIPTOR) { | ||
loop@ while (true) { | ||
when (findNextFieldIndex()) { | ||
IgnoresKeysTest.X_DESCRIPTOR.index -> x = deserializeInt() | ||
IgnoresKeysTest.Y_DESCRIPTOR.index -> y = deserializeInt() | ||
IgnoresKeysTest.Z_DESCRIPTOR.index -> z = deserializeInt() | ||
null -> break@loop | ||
} | ||
} | ||
} | ||
|
||
assertEquals(1, x) | ||
assertEquals(2, y) | ||
assertEquals(null, z) | ||
} | ||
|
||
class IgnoresMultipleKeysTest { | ||
companion object { | ||
val W_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("w")) | ||
val X_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("x")) | ||
val Y_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("y")) | ||
val Z_DESCRIPTOR = SdkFieldDescriptor(SerialKind.Integer, JsonSerialName("z")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. duplicated, can re-use the others descriptors above |
||
val OBJ_DESCRIPTOR = SdkObjectDescriptor.build { | ||
trait(IgnoreKey("w")) // <---- | ||
trait(IgnoreKey("z")) // <---- | ||
field(W_DESCRIPTOR) | ||
field(X_DESCRIPTOR) | ||
field(Y_DESCRIPTOR) | ||
field(Z_DESCRIPTOR) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun itIgnoresMultipleKeys() { | ||
val payload = """ | ||
{ | ||
"w": 0, | ||
"x": 1, | ||
"y": 2, | ||
"z": 3 | ||
} | ||
""".trimIndent().encodeToByteArray() | ||
|
||
val deserializer = JsonDeserializer(payload) | ||
var w: Int? = null | ||
var x: Int? = null | ||
var y: Int? = null | ||
var z: Int? = null | ||
deserializer.deserializeStruct(IgnoresMultipleKeysTest.OBJ_DESCRIPTOR) { | ||
loop@ while (true) { | ||
when (findNextFieldIndex()) { | ||
IgnoresMultipleKeysTest.W_DESCRIPTOR.index -> w = deserializeInt() | ||
IgnoresMultipleKeysTest.X_DESCRIPTOR.index -> x = deserializeInt() | ||
IgnoresMultipleKeysTest.Y_DESCRIPTOR.index -> y = deserializeInt() | ||
IgnoresMultipleKeysTest.Z_DESCRIPTOR.index -> z = deserializeInt() | ||
null -> break@loop | ||
} | ||
} | ||
} | ||
|
||
assertEquals(null, w) | ||
assertEquals(1, x) | ||
assertEquals(2, y) | ||
assertEquals(null, z) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style: Line length > 120 chars