From ed224aeaabd2fe58c3260f4dfee357d3d839b46c Mon Sep 17 00:00:00 2001 From: Josh Elkins Date: Tue, 21 Nov 2023 10:19:54 -0500 Subject: [PATCH] Add a header to operation doc comments --- .../smithy/swift/codegen/ServiceGenerator.kt | 2 + .../test/kotlin/ContentMd5MiddlewareTests.kt | 75 ++++++++++--------- .../HttpProtocolClientGeneratorTests.kt | 66 ++++++++-------- .../test/kotlin/IdempotencyTokenTraitTests.kt | 73 +++++++++--------- 4 files changed, 111 insertions(+), 105 deletions(-) diff --git a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/ServiceGenerator.kt b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/ServiceGenerator.kt index 66384add0..d63c59531 100644 --- a/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/ServiceGenerator.kt +++ b/smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/ServiceGenerator.kt @@ -76,6 +76,8 @@ class ServiceGenerator( * Helper method for generating in-line documentation for operation */ private fun renderOperationDoc(model: Model, service: ServiceShape, op: OperationShape, writer: SwiftWriter) { + writer.writeDocs("Performs the \\`${op.id.name}\\` operation on the \\`${service.id.name}\\` service.") + writer.writeDocs("") writer.writeShapeDocs(op) writer.writeAvailableAttribute(model, op) diff --git a/smithy-swift-codegen/src/test/kotlin/ContentMd5MiddlewareTests.kt b/smithy-swift-codegen/src/test/kotlin/ContentMd5MiddlewareTests.kt index 13eeeb1d2..a3c58ee7f 100644 --- a/smithy-swift-codegen/src/test/kotlin/ContentMd5MiddlewareTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/ContentMd5MiddlewareTests.kt @@ -6,43 +6,44 @@ class ContentMd5MiddlewareTests { fun `generates ContentMD5 middleware`() { val context = setupTests("Isolated/contentmd5checksum.smithy", "aws.protocoltests.restxml#RestXml") val contents = getFileContents(context.manifest, "/RestXml/RestXmlProtocolClient.swift") - val expectedContents = - """ - extension RestXmlProtocolClient: RestXmlProtocolClientProtocol { - /// This is a very cool operation. - /// - /// - Parameter IdempotencyTokenWithStructureInput : [no documentation found] - /// - /// - Returns: `IdempotencyTokenWithStructureOutput` : [no documentation found] - public func idempotencyTokenWithStructure(input: IdempotencyTokenWithStructureInput) async throws -> IdempotencyTokenWithStructureOutput - { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withDecoder(value: decoder) - .withMethod(value: .put) - .withServiceName(value: serviceName) - .withOperation(value: "idempotencyTokenWithStructure") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .build() - var operation = ClientRuntime.OperationStack(id: "idempotencyTokenWithStructure") - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.token)) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) - operation.buildStep.intercept(position: .before, middleware: ClientRuntime.ContentMD5Middleware()) - operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/xml")) - operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "IdempotencyToken")) - operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result - } - - } - """.trimIndent() + val expectedContents = """ +extension RestXmlProtocolClient: RestXmlProtocolClientProtocol { + /// Performs the `IdempotencyTokenWithStructure` operation on the `RestXml` service. + /// + /// This is a very cool operation. + /// + /// - Parameter IdempotencyTokenWithStructureInput : [no documentation found] + /// + /// - Returns: `IdempotencyTokenWithStructureOutput` : [no documentation found] + public func idempotencyTokenWithStructure(input: IdempotencyTokenWithStructureInput) async throws -> IdempotencyTokenWithStructureOutput + { + let context = ClientRuntime.HttpContextBuilder() + .withEncoder(value: encoder) + .withDecoder(value: decoder) + .withMethod(value: .put) + .withServiceName(value: serviceName) + .withOperation(value: "idempotencyTokenWithStructure") + .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) + .withLogger(value: config.logger) + .withPartitionID(value: config.partitionID) + .build() + var operation = ClientRuntime.OperationStack(id: "idempotencyTokenWithStructure") + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.token)) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) + operation.buildStep.intercept(position: .before, middleware: ClientRuntime.ContentMD5Middleware()) + operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/xml")) + operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "IdempotencyToken")) + operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) + let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) + return result + } + +} +""" contents.shouldContainOnlyOnce(expectedContents) } private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { diff --git a/smithy-swift-codegen/src/test/kotlin/HttpProtocolClientGeneratorTests.kt b/smithy-swift-codegen/src/test/kotlin/HttpProtocolClientGeneratorTests.kt index cb578f9b3..5324726f4 100644 --- a/smithy-swift-codegen/src/test/kotlin/HttpProtocolClientGeneratorTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/HttpProtocolClientGeneratorTests.kt @@ -106,38 +106,40 @@ class HttpProtocolClientGeneratorTests { val contents = getFileContents(context.manifest, "/RestJson/RestJsonProtocolClient.swift") contents.shouldSyntacticSanityCheck() val expected = """ - extension RestJsonProtocolClient: RestJsonProtocolClientProtocol { - /// This is a very cool operation. - /// - /// - Parameter AllocateWidgetInput : [no documentation found] - /// - /// - Returns: `AllocateWidgetOutput` : [no documentation found] - public func allocateWidget(input: AllocateWidgetInput) async throws -> AllocateWidgetOutput - { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withDecoder(value: decoder) - .withMethod(value: .post) - .withServiceName(value: serviceName) - .withOperation(value: "allocateWidget") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .build() - var operation = ClientRuntime.OperationStack(id: "allocateWidget") - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.clientToken)) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) - operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) - operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "AllocateWidgetInput")) - operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result - } - """.trimIndent() +extension RestJsonProtocolClient: RestJsonProtocolClientProtocol { + /// Performs the `AllocateWidget` operation on the `Example` service. + /// + /// This is a very cool operation. + /// + /// - Parameter AllocateWidgetInput : [no documentation found] + /// + /// - Returns: `AllocateWidgetOutput` : [no documentation found] + public func allocateWidget(input: AllocateWidgetInput) async throws -> AllocateWidgetOutput + { + let context = ClientRuntime.HttpContextBuilder() + .withEncoder(value: encoder) + .withDecoder(value: decoder) + .withMethod(value: .post) + .withServiceName(value: serviceName) + .withOperation(value: "allocateWidget") + .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) + .withLogger(value: config.logger) + .withPartitionID(value: config.partitionID) + .build() + var operation = ClientRuntime.OperationStack(id: "allocateWidget") + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.clientToken)) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) + operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/json")) + operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "AllocateWidgetInput")) + operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) + let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) + return result + } +""" contents.shouldContainOnlyOnce(expected) } diff --git a/smithy-swift-codegen/src/test/kotlin/IdempotencyTokenTraitTests.kt b/smithy-swift-codegen/src/test/kotlin/IdempotencyTokenTraitTests.kt index bf6db1240..e514406fe 100644 --- a/smithy-swift-codegen/src/test/kotlin/IdempotencyTokenTraitTests.kt +++ b/smithy-swift-codegen/src/test/kotlin/IdempotencyTokenTraitTests.kt @@ -6,42 +6,43 @@ class IdempotencyTokenTraitTests { fun `generates idempotent middleware`() { val context = setupTests("Isolated/idempotencyToken.smithy", "aws.protocoltests.restxml#RestXml") val contents = getFileContents(context.manifest, "/RestXml/RestXmlProtocolClient.swift") - val expectedContents = - """ - extension RestXmlProtocolClient: RestXmlProtocolClientProtocol { - /// This is a very cool operation. - /// - /// - Parameter IdempotencyTokenWithStructureInput : [no documentation found] - /// - /// - Returns: `IdempotencyTokenWithStructureOutput` : [no documentation found] - public func idempotencyTokenWithStructure(input: IdempotencyTokenWithStructureInput) async throws -> IdempotencyTokenWithStructureOutput - { - let context = ClientRuntime.HttpContextBuilder() - .withEncoder(value: encoder) - .withDecoder(value: decoder) - .withMethod(value: .put) - .withServiceName(value: serviceName) - .withOperation(value: "idempotencyTokenWithStructure") - .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) - .withLogger(value: config.logger) - .withPartitionID(value: config.partitionID) - .build() - var operation = ClientRuntime.OperationStack(id: "idempotencyTokenWithStructure") - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.token)) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) - operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) - operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/xml")) - operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "IdempotencyToken")) - operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) - operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) - operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) - let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) - return result - } - - } - """.trimIndent() + val expectedContents = """ +extension RestXmlProtocolClient: RestXmlProtocolClientProtocol { + /// Performs the `IdempotencyTokenWithStructure` operation on the `RestXml` service. + /// + /// This is a very cool operation. + /// + /// - Parameter IdempotencyTokenWithStructureInput : [no documentation found] + /// + /// - Returns: `IdempotencyTokenWithStructureOutput` : [no documentation found] + public func idempotencyTokenWithStructure(input: IdempotencyTokenWithStructureInput) async throws -> IdempotencyTokenWithStructureOutput + { + let context = ClientRuntime.HttpContextBuilder() + .withEncoder(value: encoder) + .withDecoder(value: decoder) + .withMethod(value: .put) + .withServiceName(value: serviceName) + .withOperation(value: "idempotencyTokenWithStructure") + .withIdempotencyTokenGenerator(value: config.idempotencyTokenGenerator) + .withLogger(value: config.logger) + .withPartitionID(value: config.partitionID) + .build() + var operation = ClientRuntime.OperationStack(id: "idempotencyTokenWithStructure") + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.IdempotencyTokenMiddleware(keyPath: \.token)) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLPathMiddleware()) + operation.initializeStep.intercept(position: .after, middleware: ClientRuntime.URLHostMiddleware()) + operation.serializeStep.intercept(position: .after, middleware: ContentTypeMiddleware(contentType: "application/xml")) + operation.serializeStep.intercept(position: .after, middleware: ClientRuntime.SerializableBodyMiddleware(xmlName: "IdempotencyToken")) + operation.finalizeStep.intercept(position: .before, middleware: ClientRuntime.ContentLengthMiddleware()) + operation.finalizeStep.intercept(position: .after, middleware: ClientRuntime.RetryMiddleware(options: config.retryStrategyOptions)) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.DeserializeMiddleware()) + operation.deserializeStep.intercept(position: .after, middleware: ClientRuntime.LoggerMiddleware(clientLogMode: config.clientLogMode)) + let result = try await operation.handleMiddleware(context: context, input: input, next: client.getHandler()) + return result + } + +} +""" contents.shouldContainOnlyOnce(expectedContents) } private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext {