Skip to content

Commit 599523c

Browse files
Be tolerant of null bodies in tests
A body with a value of None is equivalent to a body with an empty bytes value. This updates the test generator to smooth that out.
1 parent 5520941 commit 599523c

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

codegen/core/src/main/java/software/amazon/smithy/python/codegen/HttpProtocolTestGenerator.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import software.amazon.smithy.model.shapes.ShapeId;
4444
import software.amazon.smithy.model.shapes.StructureShape;
4545
import software.amazon.smithy.model.shapes.UnionShape;
46+
import software.amazon.smithy.model.traits.HttpPayloadTrait;
47+
import software.amazon.smithy.model.traits.OutputTrait;
4648
import software.amazon.smithy.model.traits.StreamingTrait;
4749
import software.amazon.smithy.model.traits.TimestampFormatTrait.Format;
4850
import software.amazon.smithy.protocoltests.traits.AppliesTo;
@@ -399,7 +401,7 @@ private void writeRequestBodyComparison(HttpMessageTestCase testCase, PythonWrit
399401
}
400402
writer.addDependency(SmithyPythonDependency.SMITHY_CORE);
401403
writer.addImport("smithy_core.aio.types", "AsyncBytesReader");
402-
writer.write("actual_body_content = await AsyncBytesReader(actual.body).read()");
404+
writer.write("actual_body_content = await AsyncBytesReader(actual.body or b'').read()");
403405
writer.write("expected_body_content = b$S", testCase.getBody().get());
404406
compareMediaBlob(testCase, writer);
405407
}
@@ -779,10 +781,20 @@ private Void structureShape(StructureShape shape, ObjectNode node) {
779781
}
780782

781783
private Void structureMemberShapes(StructureShape container, ObjectNode node) {
782-
node.getMembers().forEach((keyNode, valueNode) -> {
783-
var memberShape = container.getMember(keyNode.getValue())
784-
.orElseThrow(() -> new CodegenException("unknown memberShape: " + keyNode.getValue()));
785-
var targetShape = model.expectShape(memberShape.getTarget());
784+
for (MemberShape member : container.members()) {
785+
var optionalValueNode = node.getMember(member.getMemberName());
786+
if (optionalValueNode.isEmpty()) {
787+
if (isStringLikeOutputPayload(container, member)) {
788+
// Massage these outputs to always be present because it will generally be impossible to
789+
// determine the difference between an empty body and a missing body.
790+
optionalValueNode = Optional.of(Node.from(""));
791+
} else {
792+
continue;
793+
}
794+
}
795+
var valueNode = optionalValueNode.get();
796+
797+
var targetShape = model.expectShape(member.getTarget());
786798

787799
var formatString = "$L = $C,";
788800
if (targetShape.isDocumentShape()) {
@@ -791,12 +803,21 @@ private Void structureMemberShapes(StructureShape container, ObjectNode node) {
791803
}
792804

793805
writer.write(formatString,
794-
context.symbolProvider().toMemberName(memberShape),
806+
context.symbolProvider().toMemberName(member),
795807
(Runnable) () -> valueNode.accept(new ValueNodeVisitor(targetShape)));
796-
});
808+
809+
}
797810
return null;
798811
}
799812

813+
private boolean isStringLikeOutputPayload(StructureShape container, MemberShape member) {
814+
if (container.hasTrait(OutputTrait.class) && member.hasTrait(HttpPayloadTrait.class)) {
815+
var target = model.expectShape(member.getTarget());
816+
return target.isBlobShape() || target.isStringShape();
817+
}
818+
return false;
819+
}
820+
800821
private Void mapShape(MapShape shape, ObjectNode node) {
801822
writer.openBlock("{",
802823
"}",

0 commit comments

Comments
 (0)