diff --git a/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/endpointsV2/EndpointsV2GeneratorTest.java b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/endpointsV2/EndpointsV2GeneratorTest.java new file mode 100644 index 00000000000..ea64d04d2a2 --- /dev/null +++ b/smithy-typescript-codegen/src/test/java/software/amazon/smithy/typescript/codegen/endpointsV2/EndpointsV2GeneratorTest.java @@ -0,0 +1,91 @@ +package software.amazon.smithy.typescript.codegen.endpointsV2; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.MockManifest; +import software.amazon.smithy.build.PluginContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.node.Node; +import software.amazon.smithy.typescript.codegen.CodegenUtils; +import software.amazon.smithy.typescript.codegen.TypeScriptCodegenPlugin; + +public class EndpointsV2GeneratorTest { + @Test + public void containsTrailingSemicolon() { + MockManifest manifest = testEndpoints("endpoints.smithy"); + + String ruleset = manifest.getFileString(CodegenUtils.SOURCE_FOLDER + "/endpoint/ruleset.ts").get(); + + assertThat(ruleset, containsString( + " },\n" + + " {\n" + + " \"documentation\": \"Fallback when region is unset\",\n" + + " \"conditions\": [\n" + + " ],\n" + + " \"error\": \"Region must be set to resolve a valid endpoint\",\n" + + " \"type\": \"error\",\n" + + " },\n" + + " ],\n" + + " }\n" + + ";\n")); + } + + @Test + public void containsExtraContextParameter() { + MockManifest manifest = testEndpoints("endpoints.smithy"); + + String ruleset = manifest.getFileString(CodegenUtils.SOURCE_FOLDER + "/endpoint/ruleset.ts").get(); + + assertThat(ruleset, containsString( + " },\n" + + " \"Stage\": {\n" + + " \"type\": \"String\",\n" + + " \"required\": true,\n" + + " \"default\": \"production\",\n" + + " },\n")); + + String endpointParameters = manifest.getFileString(CodegenUtils.SOURCE_FOLDER + "/endpoint/EndpointParameters.ts").get(); + + assertThat(endpointParameters, containsString( + " return {\n" + + " ...options,\n" + + " region: options.region ?? \"us-east-1\",\n" + + " stage: options.stage ?? \"production\",\n" + + " defaultSigningName: \"\",\n" + + " }\n")); + } + + private MockManifest testEndpoints(String filename) { + MockManifest manifest = new MockManifest(); + PluginContext context = PluginContext.builder() + .pluginClassLoader(getClass().getClassLoader()) + .model(Model.assembler() + .addImport(getClass().getResource(filename)) + .discoverModels() + .assemble() + .unwrap()) + .fileManifest(manifest) + .settings(Node.objectNodeBuilder() + .withMember("service", Node.from("smithy.example#Example")) + .withMember("package", Node.from("example")) + .withMember("packageVersion", Node.from("1.0.0")) + .build()) + .build(); + + new TypeScriptCodegenPlugin().execute(context); + + assertThat(manifest.hasFile(CodegenUtils.SOURCE_FOLDER + "/endpoint/EndpointParameters.ts"), + is(true)); + assertThat(manifest.hasFile(CodegenUtils.SOURCE_FOLDER + "/endpoint/endpointResolver.ts"), + is(true)); + + String contents = manifest.getFileString(CodegenUtils.SOURCE_FOLDER + "/endpoint/ruleset.ts").get(); + + assertThat(contents, containsString("export const ruleSet: RuleSetObject")); + + return manifest; + } +} diff --git a/smithy-typescript-codegen/src/test/resources/software/amazon/smithy/typescript/codegen/endpointsV2/endpoints.smithy b/smithy-typescript-codegen/src/test/resources/software/amazon/smithy/typescript/codegen/endpointsV2/endpoints.smithy new file mode 100644 index 00000000000..1b739782d59 --- /dev/null +++ b/smithy-typescript-codegen/src/test/resources/software/amazon/smithy/typescript/codegen/endpointsV2/endpoints.smithy @@ -0,0 +1,128 @@ +$version: "2.0" + +namespace smithy.example + +@smithy.rules#endpointRuleSet({ + "version": "1.3" + "parameters": { + "Region": { + "builtIn": "AWS::Region", + "type": "String", + "required": true, + "default": "us-east-1", + "documentation": "The region to dispatch this request, eg. `us-east-1`." + }, + "Stage": { + "type": "String", + "required": true, + "default": "production" + }, + "Endpoint": { + "builtIn": "SDK::Endpoint", + "type": "String", + "required": false, + "documentation": "Override the endpoint used to send this request" + } + }, + "rules": [ + { + "conditions": [ + { + "fn": "isSet", + "argv": [ + { + "ref": "Endpoint" + } + ] + }, + { + "fn": "parseURL", + "argv": [ + { + "ref": "Endpoint" + } + ], + "assign": "url" + } + ], + "endpoint": { + "url": { + "ref": "Endpoint" + }, + "properties": {}, + "headers": {} + }, + "type": "endpoint" + }, + { + "documentation": "Template the region into the URI when region is set", + "conditions": [ + { + "fn": "isSet", + "argv": [ + { + "ref": "Region" + } + ] + } + ], + "type": "tree", + "rules": [ + { + "conditions": [ + { + "fn": "stringEquals", + "argv": [ + { + "ref": "Stage" + }, + "staging" + ] + } + ], + "endpoint": { + "url": "https://{Region}.staging.example.com/2023-01-01", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + }, + { + "conditions": [], + "endpoint": { + "url": "https://{Region}.example.com/2023-01-01", + "properties": {}, + "headers": {} + }, + "type": "endpoint" + } + ] + }, + { + "documentation": "Fallback when region is unset", + "conditions": [], + "error": "Region must be set to resolve a valid endpoint", + "type": "error" + } + ] +}) +@smithy.rules#clientContextParams( + Stage: {type: "string", documentation: "The endpoint stage used to construct the hostname."} +) +service Example { + version: "2023-01-01" + operations: [GetFoo] +} + +@readonly +operation GetFoo { + input: GetFooInput + output: GetFooOutput +} + +structure GetFooInput { + @required + @hostLabel + foo: String +} +structure GetFooOutput {}