From 0ac2c72f85cd253872519962ea0479e73d3b7eb0 Mon Sep 17 00:00:00 2001 From: George Fu Date: Fri, 24 Mar 2023 02:03:10 +0000 Subject: [PATCH 1/4] add structural hint to command examples --- .../typescript/codegen/CommandGenerator.java | 4 + .../StructureExampleGenerator.java | 282 ++++++++++++++++++ .../StructureExampleGeneratorTest.java | 93 ++++++ 3 files changed, 379 insertions(+) create mode 100644 smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java create mode 100644 smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java index f24077fc3bc..31bedf7f4e8 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/CommandGenerator.java @@ -42,6 +42,7 @@ import software.amazon.smithy.model.traits.DocumentationTrait; import software.amazon.smithy.model.traits.ErrorTrait; import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; +import software.amazon.smithy.typescript.codegen.documentation.StructureExampleGenerator; import software.amazon.smithy.typescript.codegen.endpointsV2.EndpointsParamNameMap; import software.amazon.smithy.typescript.codegen.endpointsV2.RuleSetParameterFinder; import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator; @@ -174,6 +175,9 @@ private String getCommandExample(String serviceName, String configName, String c + String.format("// const { %s, %s } = require(\"%s\"); // CommonJS import%n", serviceName, commandName, packageName) + String.format("const client = new %s(config);%n", serviceName) + + String.format("const input = %s%n", + StructureExampleGenerator.generateStructuralHintDocumentation( + model.getShape(operation.getInputShape()).get(), model)) + String.format("const command = new %s(input);%n", commandName) + "const response = await client.send(command);\n" + "```\n" diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java new file mode 100644 index 00000000000..6431a96c5e9 --- /dev/null +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java @@ -0,0 +1,282 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.typescript.codegen.documentation; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.EnumShape; +import software.amazon.smithy.model.shapes.IntEnumShape; +import software.amazon.smithy.model.shapes.ListShape; +import software.amazon.smithy.model.shapes.MapShape; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.StructureShape; +import software.amazon.smithy.model.shapes.UnionShape; +import software.amazon.smithy.model.traits.RequiredTrait; +import software.amazon.smithy.model.traits.StreamingTrait; + +/** + * Generates a structural hint for a shape used in command documentation. + */ +public abstract class StructureExampleGenerator { + /** + * Generates an example structure for API documentation, as an + * automated gap filler for operations that do not have + * hand written examples. + * + * Example for Athena::createPreparedStatement + * ```js + * const input = { + * // QueryStatement: 'STRING_VALUE', // required + * // StatementName: 'STRING_VALUE', // required + * // WorkGroup: 'STRING_VALUE', // required + * // Description: 'STRING_VALUE' + * }; + * ``` + */ + public static String generateStructuralHintDocumentation(Shape shape, Model model) { + StringBuilder buffer = new StringBuilder(); + shape(shape, buffer, model, 0, new ShapeTracker()); + + // replace non-leading whitespace with single space. + String s = Arrays.stream( + buffer.toString() + .split("\n")) + .map(line -> line.replaceAll( + "([\\w\\\",:] )\\s+", + "$1")) + .collect(Collectors.joining("\n")); + + return s; + } + + private static void structure(StructureShape structureShape, + StringBuilder buffer, Model model, + int indentation, + ShapeTracker shapeTracker) { + if (structureShape.getAllMembers().size() == 0) { + append(indentation, buffer, "{}"); + checkRequired(indentation, buffer, structureShape); + } else { + append(indentation, buffer, "{"); + checkRequired(indentation, buffer, structureShape); + structureShape.getAllMembers().values().forEach(member -> { + append(indentation + 2, buffer, member.getMemberName() + ": "); + shape(member, buffer, model, indentation + 2, shapeTracker); + }); + append(indentation, buffer, "}\n"); + } + } + + private static void union(UnionShape unionShape, + StringBuilder buffer, + Model model, + int indentation, + ShapeTracker shapeTracker) { + append(indentation, buffer, "{ // Union: only one key present"); + checkRequired(indentation, buffer, unionShape); + unionShape.getAllMembers().values().forEach(member -> { + append(indentation + 2, buffer, member.getMemberName() + ": "); + shape(member, buffer, model, indentation + 2, shapeTracker); + }); + append(indentation, buffer, "}\n"); + } + + private static void shape(Shape shape, + StringBuilder buffer, + Model model, + int indentation, + ShapeTracker shapeTracker) { + Shape target; + if (shape instanceof MemberShape) { + target = model.getShape(((MemberShape) shape).getTarget()).get(); + } else { + target = shape; + } + + shapeTracker.mark(shape, indentation); + if (shapeTracker.getOccurrenceDepths(shape) > 5) { + append(indentation, buffer, "\"<" + shape.getId().getName() + ">\""); + } else { + switch (target.getType()) { + case BIG_DECIMAL: + append(indentation, buffer, "Number('bigdecimal'),"); + break; + case BIG_INTEGER: + append(indentation, buffer, "Number('bigint'),"); + break; + case BLOB: + if (target.hasTrait(StreamingTrait.class)) { + append(indentation, buffer, "\"STREAMING_BLOB_VALUE\","); + } else { + append(indentation, buffer, "\"BLOB_VALUE\","); + } + break; + case BOOLEAN: + append(indentation, buffer, "true || false,"); + break; + case BYTE: + append(indentation, buffer, "\"BYTE_VALUE\","); + break; + case DOCUMENT: + append(indentation, buffer, "\"DOCUMENT_VALUE\","); + break; + case DOUBLE: + append(indentation, buffer, "Number('double'),"); + break; + case FLOAT: + append(indentation, buffer, "Number('float'),"); + break; + case INTEGER: + append(indentation, buffer, "Number('int'),"); + break; + case LONG: + append(indentation, buffer, "Number('long'),"); + break; + case SHORT: + append(indentation, buffer, "Number('short'),"); + break; + case STRING: + append(indentation, buffer, "\"STRING_VALUE\","); + break; + case TIMESTAMP: + append(indentation, buffer, "\"TIMESTAMP\","); + break; + + case SET: + case LIST: + append(indentation, buffer, "["); + checkRequired(indentation, buffer, shape); + ListShape list = (ListShape) target; + shape(list.getMember(), buffer, model, indentation + 2, shapeTracker); + append(indentation, buffer, "],\n"); + break; + case MAP: + append(indentation, buffer, "{"); + checkRequired(indentation, buffer, shape); + append(indentation + 2, buffer, "\"\": "); + MapShape map = (MapShape) target; + shape(model.getShape(map.getValue().getTarget()).get(), buffer, model, indentation + 2, + shapeTracker); + append(indentation, buffer, "},\n"); + break; + + case STRUCTURE: + StructureShape structure = (StructureShape) target; + structure(structure, buffer, model, indentation, shapeTracker); + break; + case UNION: + UnionShape union = (UnionShape) target; + union(union, buffer, model, indentation, shapeTracker); + break; + + case ENUM: + EnumShape enumShape = (EnumShape) target; + String enumeration = enumShape.getEnumValues() + .values() + .stream() + .map(s -> "\"" + s + "\"") + .collect(Collectors.joining(" || ")); + append(indentation, buffer, enumeration); + break; + case INT_ENUM: + IntEnumShape intEnumShape = (IntEnumShape) target; + String intEnumeration = intEnumShape.getEnumValues() + .values() + .stream() + .map(i -> Integer.toString(i)) + .collect(Collectors.joining(" || ")); + append(indentation, buffer, intEnumeration); + break; + case OPERATION: + case RESOURCE: + case SERVICE: + case MEMBER: + default: + append(indentation, buffer, "\"...\","); + break; + } + } + + switch (target.getType()) { + case STRUCTURE: + case UNION: + case LIST: + case SET: + case MAP: + break; + case BIG_DECIMAL: + case BIG_INTEGER: + case BLOB: + case BOOLEAN: + case BYTE: + case DOCUMENT: + case DOUBLE: + case ENUM: + case FLOAT: + case INTEGER: + case INT_ENUM: + case LONG: + case MEMBER: + case OPERATION: + case RESOURCE: + case SERVICE: + case SHORT: + case STRING: + case TIMESTAMP: + default: + checkRequired(indentation, buffer, shape); + break; + } + } + + private static void checkRequired(int indentation, StringBuilder buffer, Shape shape) { + if (shape.hasTrait(RequiredTrait.class)) { + append(indentation, buffer, " // required\n"); + } else { + append(indentation, buffer, "\n"); + } + } + + private static void append(int indentation, StringBuilder buffer, String tail) { + while (indentation-- > 0) { + buffer.append(" "); + } + buffer.append(tail); + } + + /** + * Tracks the depths at which a shape appears in the tree. + * If a shape appears at too many depths it is truncated. + * This handles the case of recursive shapes. + */ + private static class ShapeTracker { + private Map> data = new HashMap>(); + + /** + * Mark that a shape is observed at depth. + */ + public void mark(Shape shape, int depth) { + if (!data.containsKey(shape)) { + data.put(shape, new HashSet<>()); + } + data.get(shape).add(depth); + } + + /** + * @return the number of distinct depths in which the shape appears. + */ + public int getOccurrenceDepths(Shape shape) { + return data.getOrDefault(shape, Collections.emptySet()).size(); + } + } +} diff --git a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java new file mode 100644 index 00000000000..e55e2055df3 --- /dev/null +++ b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java @@ -0,0 +1,93 @@ +package software.amazon.smithy.typescript.codegen.documentation; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import java.util.List; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ListShape; +import software.amazon.smithy.model.shapes.MapShape; +import software.amazon.smithy.model.shapes.MemberShape; +import software.amazon.smithy.model.shapes.StringShape; +import software.amazon.smithy.model.shapes.StructureShape; + +public class StructureExampleGeneratorTest { + + StringShape string = StringShape.builder() + .id("foo.bar#string") + .build(); + + ListShape list = ListShape.builder() + .id("foo.bar#list") + .member(string.getId()) + .build(); + + MapShape map = MapShape.builder() + .id("foo.bar#map") + .key(MemberShape.builder() + .id("foo.bar#map$member") + .target(string.getId()) + .build()) + .value(MemberShape.builder() + .id("foo.bar#map$member") + .target(string.getId()) + .build()) + .build(); + + MemberShape memberForString = MemberShape.builder() + .id("foo.bar#structure$string") + .target(string.getId()) + .build(); + + MemberShape memberForList = MemberShape.builder() + .id("foo.bar#structure$list") + .target(list.getId()) + .build(); + + MemberShape memberForMap = MemberShape.builder() + .id("foo.bar#structure$map") + .target(map.getId()) + .build(); + + StructureShape structure = StructureShape.builder() + .id("foo.bar#structure") + .members( + List.of(memberForString, memberForList, memberForMap)) + .build(); + + private Model model = Model.builder() + .addShapes( + string, list, map, structure, + memberForString, memberForList, memberForMap) + .build(); + + @Test + public void generatesStructuralHintDocumentation_map() { + assertThat( + StructureExampleGenerator.generateStructuralHintDocumentation(map, model), + equalTo("{\n \"\": \"STRING_VALUE\", \n},")); + } + + @Test + public void generatesStructuralHintDocumentation_structure() { + assertThat( + StructureExampleGenerator.generateStructuralHintDocumentation(structure, model), + equalTo("{\n" + + " string: \"STRING_VALUE\", \n" + + " list: [ \n" + + " \"STRING_VALUE\", \n" + + " ],\n" + + " map: { \n" + + " \"\": \"STRING_VALUE\", \n" + + " },\n" + + "}")); + } + + @Test + public void generatesStructuralHintDocumentation_list() { + assertThat( + StructureExampleGenerator.generateStructuralHintDocumentation(list, model), + equalTo("[\n \"STRING_VALUE\", \n],")); + } +} From aff5e13a0ca8259103c3c1eccad509c1ca1ca5f5 Mon Sep 17 00:00:00 2001 From: George Fu Date: Fri, 24 Mar 2023 17:17:32 +0000 Subject: [PATCH 2/4] formatting fixes --- .../StructureExampleGenerator.java | 78 +++++++++---------- .../StructureExampleGeneratorTest.java | 10 +-- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java index 6431a96c5e9..3cef8f2d8b0 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java @@ -52,11 +52,11 @@ public static String generateStructuralHintDocumentation(Shape shape, Model mode buffer.toString() .split("\n")) .map(line -> line.replaceAll( - "([\\w\\\",:] )\\s+", + "([\\w\\\",:\\[\\{] )\\s+", "$1")) .collect(Collectors.joining("\n")); - return s; + return s.replaceAll(",$", ";"); } private static void structure(StructureShape structureShape, @@ -64,7 +64,7 @@ private static void structure(StructureShape structureShape, int indentation, ShapeTracker shapeTracker) { if (structureShape.getAllMembers().size() == 0) { - append(indentation, buffer, "{}"); + append(indentation, buffer, "{},"); checkRequired(indentation, buffer, structureShape); } else { append(indentation, buffer, "{"); @@ -73,7 +73,7 @@ private static void structure(StructureShape structureShape, append(indentation + 2, buffer, member.getMemberName() + ": "); shape(member, buffer, model, indentation + 2, shapeTracker); }); - append(indentation, buffer, "}\n"); + append(indentation, buffer, "},\n"); } } @@ -88,7 +88,7 @@ private static void union(UnionShape unionShape, append(indentation + 2, buffer, member.getMemberName() + ": "); shape(member, buffer, model, indentation + 2, shapeTracker); }); - append(indentation, buffer, "}\n"); + append(indentation, buffer, "},\n"); } private static void shape(Shape shape, @@ -104,8 +104,8 @@ private static void shape(Shape shape, } shapeTracker.mark(shape, indentation); - if (shapeTracker.getOccurrenceDepths(shape) > 5) { - append(indentation, buffer, "\"<" + shape.getId().getName() + ">\""); + if (shapeTracker.getOccurrenceDepths(shape) > 2) { + append(indentation, buffer, "\"<" + shape.getId().getName() + ">\",\n"); } else { switch (target.getType()) { case BIG_DECIMAL: @@ -186,7 +186,7 @@ private static void shape(Shape shape, .stream() .map(s -> "\"" + s + "\"") .collect(Collectors.joining(" || ")); - append(indentation, buffer, enumeration); + append(indentation, buffer, enumeration + ","); break; case INT_ENUM: IntEnumShape intEnumShape = (IntEnumShape) target; @@ -195,7 +195,7 @@ private static void shape(Shape shape, .stream() .map(i -> Integer.toString(i)) .collect(Collectors.joining(" || ")); - append(indentation, buffer, intEnumeration); + append(indentation, buffer, intEnumeration + ","); break; case OPERATION: case RESOURCE: @@ -205,37 +205,37 @@ private static void shape(Shape shape, append(indentation, buffer, "\"...\","); break; } - } - switch (target.getType()) { - case STRUCTURE: - case UNION: - case LIST: - case SET: - case MAP: - break; - case BIG_DECIMAL: - case BIG_INTEGER: - case BLOB: - case BOOLEAN: - case BYTE: - case DOCUMENT: - case DOUBLE: - case ENUM: - case FLOAT: - case INTEGER: - case INT_ENUM: - case LONG: - case MEMBER: - case OPERATION: - case RESOURCE: - case SERVICE: - case SHORT: - case STRING: - case TIMESTAMP: - default: - checkRequired(indentation, buffer, shape); - break; + switch (target.getType()) { + case STRUCTURE: + case UNION: + case LIST: + case SET: + case MAP: + break; + case BIG_DECIMAL: + case BIG_INTEGER: + case BLOB: + case BOOLEAN: + case BYTE: + case DOCUMENT: + case DOUBLE: + case ENUM: + case FLOAT: + case INTEGER: + case INT_ENUM: + case LONG: + case MEMBER: + case OPERATION: + case RESOURCE: + case SERVICE: + case SHORT: + case STRING: + case TIMESTAMP: + default: + checkRequired(indentation, buffer, shape); + break; + } } } diff --git a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java index e55e2055df3..41abd0b466b 100644 --- a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java +++ b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java @@ -66,7 +66,7 @@ public class StructureExampleGeneratorTest { public void generatesStructuralHintDocumentation_map() { assertThat( StructureExampleGenerator.generateStructuralHintDocumentation(map, model), - equalTo("{\n \"\": \"STRING_VALUE\", \n},")); + equalTo("{\n \"\": \"STRING_VALUE\", \n};")); } @Test @@ -75,19 +75,19 @@ public void generatesStructuralHintDocumentation_structure() { StructureExampleGenerator.generateStructuralHintDocumentation(structure, model), equalTo("{\n" + " string: \"STRING_VALUE\", \n" - + " list: [ \n" + + " list: [ \n" + " \"STRING_VALUE\", \n" + " ],\n" - + " map: { \n" + + " map: { \n" + " \"\": \"STRING_VALUE\", \n" + " },\n" - + "}")); + + "};")); } @Test public void generatesStructuralHintDocumentation_list() { assertThat( StructureExampleGenerator.generateStructuralHintDocumentation(list, model), - equalTo("[\n \"STRING_VALUE\", \n],")); + equalTo("[\n \"STRING_VALUE\", \n];")); } } From fedabb1ee722cc01126e4b6f7e557422efe9eb86 Mon Sep 17 00:00:00 2001 From: George Fu Date: Fri, 24 Mar 2023 17:54:30 +0000 Subject: [PATCH 3/4] timestamp format --- .../documentation/StructureExampleGenerator.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java index 3cef8f2d8b0..27dbce9321f 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java @@ -109,10 +109,10 @@ private static void shape(Shape shape, } else { switch (target.getType()) { case BIG_DECIMAL: - append(indentation, buffer, "Number('bigdecimal'),"); + append(indentation, buffer, "Number(\"bigdecimal\"),"); break; case BIG_INTEGER: - append(indentation, buffer, "Number('bigint'),"); + append(indentation, buffer, "Number(\"bigint\"),"); break; case BLOB: if (target.hasTrait(StreamingTrait.class)) { @@ -131,25 +131,25 @@ private static void shape(Shape shape, append(indentation, buffer, "\"DOCUMENT_VALUE\","); break; case DOUBLE: - append(indentation, buffer, "Number('double'),"); + append(indentation, buffer, "Number(\"double\"),"); break; case FLOAT: - append(indentation, buffer, "Number('float'),"); + append(indentation, buffer, "Number(\"float\"),"); break; case INTEGER: - append(indentation, buffer, "Number('int'),"); + append(indentation, buffer, "Number(\"int\"),"); break; case LONG: - append(indentation, buffer, "Number('long'),"); + append(indentation, buffer, "Number(\"long\"),"); break; case SHORT: - append(indentation, buffer, "Number('short'),"); + append(indentation, buffer, "Number(\"short\"),"); break; case STRING: append(indentation, buffer, "\"STRING_VALUE\","); break; case TIMESTAMP: - append(indentation, buffer, "\"TIMESTAMP\","); + append(indentation, buffer, "new Date(\"TIMESTAMP\"),"); break; case SET: From f7e5472b927f48d0b15eb036b12ea71671726355 Mon Sep 17 00:00:00 2001 From: George Fu Date: Fri, 24 Mar 2023 19:15:24 +0000 Subject: [PATCH 4/4] use java text blocks --- .../StructureExampleGenerator.java | 3 +- .../StructureExampleGeneratorTest.java | 29 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java index 27dbce9321f..d6160b0a4da 100644 --- a/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java +++ b/smithy-typescript-codegen/src/main/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGenerator.java @@ -53,7 +53,8 @@ public static String generateStructuralHintDocumentation(Shape shape, Model mode .split("\n")) .map(line -> line.replaceAll( "([\\w\\\",:\\[\\{] )\\s+", - "$1")) + "$1") + .replaceAll("\\s+$", "")) .collect(Collectors.joining("\n")); return s.replaceAll(",$", ";"); diff --git a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java index 41abd0b466b..9f769eb73a6 100644 --- a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java +++ b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/documentation/StructureExampleGeneratorTest.java @@ -66,28 +66,35 @@ public class StructureExampleGeneratorTest { public void generatesStructuralHintDocumentation_map() { assertThat( StructureExampleGenerator.generateStructuralHintDocumentation(map, model), - equalTo("{\n \"\": \"STRING_VALUE\", \n};")); + equalTo(""" + { + "": "STRING_VALUE", + };""")); } @Test public void generatesStructuralHintDocumentation_structure() { assertThat( StructureExampleGenerator.generateStructuralHintDocumentation(structure, model), - equalTo("{\n" - + " string: \"STRING_VALUE\", \n" - + " list: [ \n" - + " \"STRING_VALUE\", \n" - + " ],\n" - + " map: { \n" - + " \"\": \"STRING_VALUE\", \n" - + " },\n" - + "};")); + equalTo(""" + { + string: "STRING_VALUE", + list: [ + "STRING_VALUE", + ], + map: { + "": "STRING_VALUE", + }, + };""")); } @Test public void generatesStructuralHintDocumentation_list() { assertThat( StructureExampleGenerator.generateStructuralHintDocumentation(list, model), - equalTo("[\n \"STRING_VALUE\", \n];")); + equalTo(""" + [ + "STRING_VALUE", + ];""")); } }