Skip to content

Commit

Permalink
Add SSDK codegen test (smithy-lang#825)
Browse files Browse the repository at this point in the history
  • Loading branch information
srchase authored Jul 12, 2023
1 parent 0d97d66 commit c80e42b
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 1 deletion.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ subprojects {
* Java
* ====================================================
*/
if (subproject.name != "smithy-typescript-codegen-test") {
if (subproject.name == "smithy-typescript-codegen") {
apply(plugin = "java-library")

java {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import java.nio.charset.StandardCharsets.UTF_8
rootProject.name = "smithy-typescript"
include(":smithy-typescript-codegen")
include(":smithy-typescript-codegen-test")
include(":smithy-typescript-ssdk-codegen-test-utils")

file(
java.nio.file.Paths.get(rootProject.projectDir.absolutePath, "local.properties"))
Expand Down
1 change: 1 addition & 0 deletions smithy-typescript-codegen-test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ repositories {

dependencies {
implementation(project(":smithy-typescript-codegen"))
implementation(project(":smithy-typescript-ssdk-codegen-test-utils"))
implementation("software.amazon.smithy:smithy-waiters:$smithyVersion")
implementation("software.amazon.smithy:smithy-protocol-test-traits:$smithyVersion")
}
2 changes: 2 additions & 0 deletions smithy-typescript-codegen-test/model/main.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use smithy.waiters#waitable

/// Provides weather forecasts.
@fakeProtocol
@httpApiKeyAuth(name: "X-Api-Key", in: "header")
@paginated(inputToken: "nextToken", outputToken: "nextToken", pageSize: "pageSize")
service Weather {
version: "2006-03-01",
Expand Down Expand Up @@ -317,6 +318,7 @@ blob CityImageData

@readonly
@http(method: "GET", uri: "/cities/{cityId}/announcements")
@tags(["client-only"])
operation GetCityAnnouncements {
input: GetCityAnnouncementsInput,
output: GetCityAnnouncementsOutput,
Expand Down
24 changes: 24 additions & 0 deletions smithy-typescript-codegen-test/smithy-build.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
{
"version": "1.0",
"projections": {
"ssdk-test": {
"transforms": [
{
"name": "excludeShapesByTag",
"args": {
"tags": ["client-only"]
}
}
],
"plugins": {
"typescript-ssdk-codegen": {
"service": "example.weather#Weather",
"targetNamespace": "Weather",
"package": "weather",
"packageVersion": "0.0.1",
"packageJson": {
"license": "Apache-2.0"
},
"disableDefaultValidation": true
}
}
}
},
"plugins": {
"typescript-codegen": {
"service": "example.weather#Weather",
Expand Down
32 changes: 32 additions & 0 deletions smithy-typescript-ssdk-codegen-test-utils/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
extra["displayName"] = "Smithy :: Typescript :: SSDK :: Codegen :: Test :: Utils"
extra["moduleName"] = "software.amazon.smithy.typescript.ssdk.codegen.test.utils"

val smithyVersion: String by project

buildscript {
val smithyVersion: String by project

repositories {
mavenLocal()
mavenCentral()
}
dependencies {
"classpath"("software.amazon.smithy:smithy-cli:$smithyVersion")
}
}

plugins {
val smithyGradleVersion: String by project

id("software.amazon.smithy").version(smithyGradleVersion)
}

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation(project(":smithy-typescript-codegen"))
implementation("software.amazon.smithy:smithy-model:$smithyVersion")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package software.amazon.smithy.typescript.ssdk.codegen.test.utils;

import java.util.List;
import software.amazon.smithy.typescript.codegen.integration.ProtocolGenerator;
import software.amazon.smithy.typescript.codegen.integration.TypeScriptIntegration;
import software.amazon.smithy.utils.ListUtils;
import software.amazon.smithy.utils.SmithyInternalApi;

/**
* Adds fake protocols.
*/
@SmithyInternalApi
public class AddProtocols implements TypeScriptIntegration {

@Override
public List<ProtocolGenerator> getProtocolGenerators() {
return ListUtils.of(new TestProtocolGenerator());
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package software.amazon.smithy.typescript.ssdk.codegen.test.utils;

import java.util.List;
import java.util.Set;
import software.amazon.smithy.model.knowledge.HttpBinding;
import software.amazon.smithy.model.shapes.OperationShape;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.shapes.ShapeId;
import software.amazon.smithy.model.shapes.StructureShape;
import software.amazon.smithy.model.traits.TimestampFormatTrait.Format;
import software.amazon.smithy.typescript.codegen.TypeScriptDependency;
import software.amazon.smithy.typescript.codegen.TypeScriptWriter;
import software.amazon.smithy.typescript.codegen.integration.HttpBindingProtocolGenerator;
import software.amazon.smithy.utils.SmithyInternalApi;


/**
* Protocol for SSDK codegen testing.
*/
@SmithyInternalApi
class TestProtocolGenerator extends HttpBindingProtocolGenerator {

TestProtocolGenerator() {
super(true);
}

@Override
public ShapeId getProtocol() {
return ShapeId.from("example.weather#fakeProtocol");
}

@Override
public String getName() {
return "fakeProtocol";
}

@Override
protected String getDocumentContentType() {
return "application/json";
}

@Override
public Format getDocumentTimestampFormat() {
return Format.EPOCH_SECONDS;
}

@Override
public boolean requiresNumericEpochSecondsInPayload() {
return true;
}

@Override
public boolean enableSerdeElision() {
return true;
}

@Override
public void deserializeErrorDocumentBody(
GenerationContext context,
StructureShape error,
List<HttpBinding> documentBindings
) {}

@Override
public void serializeErrorDocumentBody(
GenerationContext context,
StructureShape error,
List<HttpBinding> documentBindings
) {}

@Override
public void deserializeInputDocumentBody(
GenerationContext context,
OperationShape operation,
List<HttpBinding> documentBindings
) {}

@Override
public void serializeInputDocumentBody(
GenerationContext context,
OperationShape operation,
List<HttpBinding> documentBindings
) {}

@Override
public void deserializeOutputDocumentBody(
GenerationContext context,
OperationShape error,
List<HttpBinding> documentBindings
) {}

@Override
public void serializeOutputDocumentBody(
GenerationContext context,
OperationShape error,
List<HttpBinding> documentBindings
) {}

@Override
public void serializeInputEventDocumentPayload(GenerationContext context) {}

@Override
public void generateDocumentBodyShapeSerializers(GenerationContext context, Set<Shape> shapes) {}

@Override
public void generateDocumentBodyShapeDeserializers(GenerationContext context, Set<Shape> shapes) {}

@Override
public void writeErrorCodeParser(GenerationContext context) {
TypeScriptWriter writer = context.getWriter();
writer.write("const errorCode = parseErrorCode(output, parsedOutput.body);");
}

@Override
public void generateProtocolTests(GenerationContext context) {}

@Override
public void generateSharedComponents(GenerationContext context) {
super.generateSharedComponents(context);

TypeScriptWriter writer = context.getWriter();

// Include a JSON body parser used to deserialize documents from HTTP responses.
writer.addImport("SerdeContext", "__SerdeContext", TypeScriptDependency.SMITHY_TYPES);
writer.openBlock("const parseBody = (streamBody: any, context: __SerdeContext): "
+ "any => collectBodyString(streamBody, context).then(encoded => {", "});", () -> {
writer.openBlock("if (encoded.length) {", "}", () -> {
writer.write("return JSON.parse(encoded);");
});
writer.write("return {};");
});
writer.write("");

// Include a JSON body parser.
writer.addImport("SerdeContext", "__SerdeContext", TypeScriptDependency.SMITHY_TYPES);
writer.openBlock("const parseErrorBody = async (errorBody: any, context: __SerdeContext) => {",
"}", () -> {
writer.write("const value = await parseBody(errorBody, context);");
writer.write("value.message = value.message ?? value.Message;");
writer.write("return value;");
});
writer.write("");

// Include an error code parser.
writer.openBlock("const parseErrorCode = (output: __HttpResponse, data: any): string | undefined => {",
"}", () -> {
writer.openBlock("if (output.headers[\"x-error\"]) {", "}", () -> {
writer.write("return output.headers[\"x-error\"];");
});
writer.openBlock("if (data.code !== undefined) {", "}", () -> {
writer.write("return data.code;");
});
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
software.amazon.smithy.typescript.ssdk.codegen.test.utils.AddProtocols

0 comments on commit c80e42b

Please sign in to comment.