diff --git a/Tests/GRPCCodeGenTests/Internal/Translator/ClientCodeTranslatorSnippetBasedTests.swift b/Tests/GRPCCodeGenTests/Internal/Translator/ClientCodeTranslatorSnippetBasedTests.swift index cfb72633c..d27bdc674 100644 --- a/Tests/GRPCCodeGenTests/Internal/Translator/ClientCodeTranslatorSnippetBasedTests.swift +++ b/Tests/GRPCCodeGenTests/Internal/Translator/ClientCodeTranslatorSnippetBasedTests.swift @@ -14,14 +14,14 @@ * limitations under the License. */ -#if os(macOS) || os(Linux) // swift-format doesn't like canImport(Foundation.Process) - -import XCTest +import Testing @testable import GRPCCodeGen -final class ClientCodeTranslatorSnippetBasedTests: XCTestCase { - func testClientCodeTranslatorUnaryMethod() throws { +@Suite +struct ClientCodeTranslatorSnippetBasedTests { + @Test + func translate() { let method = MethodDescriptor( documentation: "/// Documentation for MethodA", name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), @@ -30,14 +30,15 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase { inputType: "NamespaceA_ServiceARequest", outputType: "NamespaceA_ServiceAResponse" ) + let service = ServiceDescriptor( documentation: "/// Documentation for ServiceA", name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), namespace: Name(base: "namespaceA", generatedUpperCase: "NamespaceA", generatedLowerCase: ""), methods: [method] ) - let expectedSwift = - """ + + let expectedSwift = """ /// Documentation for ServiceA @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) public protocol NamespaceA_ServiceA_ClientProtocol: Sendable { @@ -121,694 +122,22 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase { } """ - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - func testClientCodeTranslatorClientStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: true, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name(base: "namespaceA", generatedUpperCase: "NamespaceA", generatedLowerCase: ""), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ClientProtocol: Sendable { - /// Documentation for MethodA - func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - public func methodA( - request: GRPCCore.StreamingClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.methodA( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - /// Documentation for MethodA - public func methodA( - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.StreamingClientRequest( - metadata: metadata, - producer: producer - ) - return try await self.methodA( - request: request, - options: options, - onResponse: handleResponse - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public struct NamespaceA_ServiceA_Client: NamespaceA_ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - public init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - - /// Documentation for MethodA - public func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.client.clientStreaming( - request: request, - descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) + let rendered = self.render(accessLevel: .public, service: service) + #expect(rendered == expectedSwift) } - func testClientCodeTranslatorServerStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: false, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name(base: "namespaceA", generatedUpperCase: "NamespaceA", generatedLowerCase: ""), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ClientProtocol: Sendable { - /// Documentation for MethodA - func methodA( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - public func methodA( - request: GRPCCore.ClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.methodA( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - /// Documentation for MethodA - public func methodA( - _ message: NamespaceA_ServiceARequest, - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.ClientRequest( - message: message, - metadata: metadata - ) - return try await self.methodA( - request: request, - options: options, - onResponse: handleResponse - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public struct NamespaceA_ServiceA_Client: NamespaceA_ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - public init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - - /// Documentation for MethodA - public func methodA( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.client.serverStreaming( - request: request, - descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - func testClientCodeTranslatorBidirectionalStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: true, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name(base: "namespaceA", generatedUpperCase: "NamespaceA", generatedLowerCase: ""), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ClientProtocol: Sendable { - /// Documentation for MethodA - func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - public func methodA( - request: GRPCCore.StreamingClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.methodA( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - /// Documentation for MethodA - public func methodA( - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.StreamingClientRequest( - metadata: metadata, - producer: producer - ) - return try await self.methodA( - request: request, - options: options, - onResponse: handleResponse - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public struct NamespaceA_ServiceA_Client: NamespaceA_ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - public init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - - /// Documentation for MethodA - public func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.client.bidirectionalStreaming( - request: request, - descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - func testClientCodeTranslatorMultipleMethod() throws { - let methodA = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: true, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let methodB = MethodDescriptor( - documentation: "/// Documentation for MethodB", - name: Name(base: "MethodB", generatedUpperCase: "MethodB", generatedLowerCase: "methodB"), - isInputStreaming: false, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name(base: "namespaceA", generatedUpperCase: "NamespaceA", generatedLowerCase: ""), - methods: [methodA, methodB] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package protocol NamespaceA_ServiceA_ClientProtocol: Sendable { - /// Documentation for MethodA - func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - - /// Documentation for MethodB - func methodB( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - package func methodA( - request: GRPCCore.StreamingClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.methodA( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - - package func methodB( - request: GRPCCore.ClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.methodB( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - /// Documentation for MethodA - package func methodA( - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.StreamingClientRequest( - metadata: metadata, - producer: producer - ) - return try await self.methodA( - request: request, - options: options, - onResponse: handleResponse - ) - } - - /// Documentation for MethodB - package func methodB( - _ message: NamespaceA_ServiceARequest, - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.ClientRequest( - message: message, - metadata: metadata - ) - return try await self.methodB( - request: request, - options: options, - onResponse: handleResponse - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package struct NamespaceA_ServiceA_Client: NamespaceA_ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - package init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - - /// Documentation for MethodA - package func methodA( - request: GRPCCore.StreamingClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.client.clientStreaming( - request: request, - descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - - /// Documentation for MethodB - package func methodB( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable { - try await self.client.serverStreaming( - request: request, - descriptor: NamespaceA_ServiceA.Method.MethodB.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .package - ) - } - - func testClientCodeTranslatorNoNamespaceService() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: false, - isOutputStreaming: false, - inputType: "ServiceARequest", - outputType: "ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal protocol ServiceA_ClientProtocol: Sendable { - /// Documentation for MethodA - func methodA( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result - ) async throws -> Result where Result: Sendable - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceA.ClientProtocol { - internal func methodA( - request: GRPCCore.ClientRequest, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.methodA( - request: request, - serializer: GRPCProtobuf.ProtobufSerializer(), - deserializer: GRPCProtobuf.ProtobufDeserializer(), - options: options, - onResponse: handleResponse - ) - } - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceA.ClientProtocol { - /// Documentation for MethodA - internal func methodA( - _ message: ServiceARequest, - metadata: GRPCCore.Metadata = [:], - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - let request = GRPCCore.ClientRequest( - message: message, - metadata: metadata - ) - return try await self.methodA( - request: request, - options: options, - onResponse: handleResponse - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal struct ServiceA_Client: ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - internal init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - - /// Documentation for MethodA - internal func methodA( - request: GRPCCore.ClientRequest, - serializer: some GRPCCore.MessageSerializer, - deserializer: some GRPCCore.MessageDeserializer, - options: GRPCCore.CallOptions = .defaults, - onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse) async throws -> Result = { response in - try response.message - } - ) async throws -> Result where Result: Sendable { - try await self.client.unary( - request: request, - descriptor: ServiceA.Method.MethodA.descriptor, - serializer: serializer, - deserializer: deserializer, - options: options, - onResponse: handleResponse - ) - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .internal - ) - } - - func testClientCodeTranslatorMultipleServices() throws { - let serviceA = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: ""), - namespace: Name( - base: "nammespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "" - ), - methods: [] - ) - let serviceB = ServiceDescriptor( - documentation: """ - /// Documentation for ServiceB - /// - /// Line 2 - """, - name: Name(base: "ServiceB", generatedUpperCase: "ServiceB", generatedLowerCase: ""), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ClientProtocol: Sendable {} - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ClientProtocol { - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public struct NamespaceA_ServiceA_Client: NamespaceA_ServiceA.ClientProtocol { - private let client: GRPCCore.GRPCClient - - public init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - } - /// Documentation for ServiceB - /// - /// Line 2 - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol ServiceB_ClientProtocol: Sendable {} - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceB.ClientProtocol { - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceB.ClientProtocol { - } - /// Documentation for ServiceB - /// - /// Line 2 - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public struct ServiceB_Client: ServiceB.ClientProtocol { - private let client: GRPCCore.GRPCClient - - public init(wrapping client: GRPCCore.GRPCClient) { - self.client = client - } - } - """ - - try self.assertClientCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceA, serviceB]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - private func assertClientCodeTranslation( - codeGenerationRequest request: CodeGenerationRequest, - expectedSwift: String, - accessLevel: SourceGenerator.Config.AccessLevel, - file: StaticString = #filePath, - line: UInt = #line - ) throws { - let translator = ClientCodeTranslator() - let codeBlocks = translator.translate( - accessModifier: AccessModifier(accessLevel), - services: request.services, - serializer: request.lookupSerializer, - deserializer: request.lookupDeserializer - ) - let renderer = TextBasedRenderer.default - renderer.renderCodeBlocks(codeBlocks) - let contents = renderer.renderedContents() - try XCTAssertEqualWithDiff(contents, expectedSwift, file: file, line: line) + private func render( + accessLevel: AccessModifier, + service: ServiceDescriptor + ) -> String { + let translator = ClientCodeTranslator() + let codeBlocks = translator.translate(accessModifier: accessLevel, services: [service]) { + "GRPCProtobuf.ProtobufSerializer<\($0)>()" + } deserializer: { + "GRPCProtobuf.ProtobufDeserializer<\($0)>()" + } + let renderer = TextBasedRenderer.default + renderer.renderCodeBlocks(codeBlocks) + return renderer.renderedContents() } } - -#endif // os(macOS) || os(Linux) diff --git a/Tests/GRPCCodeGenTests/Internal/Translator/ServerCodeTranslatorSnippetBasedTests.swift b/Tests/GRPCCodeGenTests/Internal/Translator/ServerCodeTranslatorSnippetBasedTests.swift index a7a17c575..e2b047ade 100644 --- a/Tests/GRPCCodeGenTests/Internal/Translator/ServerCodeTranslatorSnippetBasedTests.swift +++ b/Tests/GRPCCodeGenTests/Internal/Translator/ServerCodeTranslatorSnippetBasedTests.swift @@ -14,14 +14,14 @@ * limitations under the License. */ -#if os(macOS) || os(Linux) // swift-format doesn't like canImport(Foundation.Process) - -import XCTest +import Testing @testable import GRPCCodeGen -final class ServerCodeTranslatorSnippetBasedTests: XCTestCase { - func testServerCodeTranslatorUnaryMethod() throws { +@Suite +final class ServerCodeTranslatorSnippetBasedTests { + @Test + func translate() { let method = MethodDescriptor( documentation: "/// Documentation for unaryMethod", name: Name(base: "UnaryMethod", generatedUpperCase: "Unary", generatedLowerCase: "unary"), @@ -30,6 +30,7 @@ final class ServerCodeTranslatorSnippetBasedTests: XCTestCase { inputType: "NamespaceA_ServiceARequest", outputType: "NamespaceA_ServiceAResponse" ) + let service = ServiceDescriptor( documentation: "/// Documentation for ServiceA", name: Name( @@ -44,8 +45,8 @@ final class ServerCodeTranslatorSnippetBasedTests: XCTestCase { ), methods: [method] ) - let expectedSwift = - """ + + let expectedSwift = """ /// Documentation for ServiceA @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { @@ -98,558 +99,23 @@ final class ServerCodeTranslatorSnippetBasedTests: XCTestCase { } """ - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - func testServerCodeTranslatorInputStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for inputStreamingMethod", - name: Name( - base: "InputStreamingMethod", - generatedUpperCase: "InputStreaming", - generatedLowerCase: "inputStreaming" - ), - isInputStreaming: true, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { - /// Documentation for inputStreamingMethod - func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package func registerMethods(with router: inout GRPCCore.RPCRouter) { - router.registerHandler( - forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.inputStreaming( - request: request, - context: context - ) - } - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol { - /// Documentation for inputStreamingMethod - func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.ServerResponse - } - /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ServiceProtocol { - package func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse { - let response = try await self.inputStreaming( - request: request, - context: context - ) - return GRPCCore.StreamingServerResponse(single: response) - } - } - """ - - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .package - ) - } - - func testServerCodeTranslatorOutputStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for outputStreamingMethod", - name: Name( - base: "OutputStreamingMethod", - generatedUpperCase: "OutputStreaming", - generatedLowerCase: "outputStreaming" - ), - isInputStreaming: false, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name( - base: "ServiceATest", - generatedUpperCase: "ServiceA", - generatedLowerCase: "serviceA" - ), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { - /// Documentation for outputStreamingMethod - func outputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public func registerMethods(with router: inout GRPCCore.RPCRouter) { - router.registerHandler( - forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.outputStreaming( - request: request, - context: context - ) - } - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol { - /// Documentation for outputStreamingMethod - func outputStreaming( - request: GRPCCore.ServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ServiceProtocol { - public func outputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse { - let response = try await self.outputStreaming( - request: GRPCCore.ServerRequest(stream: request), - context: context - ) - return response - } - } - """ - - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - func testServerCodeTranslatorBidirectionalStreamingMethod() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for bidirectionalStreamingMethod", - name: Name( - base: "BidirectionalStreamingMethod", - generatedUpperCase: "BidirectionalStreaming", - generatedLowerCase: "bidirectionalStreaming" - ), - isInputStreaming: true, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name( - base: "ServiceATest", - generatedUpperCase: "ServiceA", - generatedLowerCase: "serviceA" - ), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { - /// Documentation for bidirectionalStreamingMethod - func bidirectionalStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package func registerMethods(with router: inout GRPCCore.RPCRouter) { - router.registerHandler( - forMethod: NamespaceA_ServiceA.Method.BidirectionalStreaming.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.bidirectionalStreaming( - request: request, - context: context - ) - } - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol { - /// Documentation for bidirectionalStreamingMethod - func bidirectionalStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ServiceProtocol { - } - """ - - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .package - ) - } - - func testServerCodeTranslatorMultipleMethods() throws { - let inputStreamingMethod = MethodDescriptor( - documentation: "/// Documentation for inputStreamingMethod", - name: Name( - base: "InputStreamingMethod", - generatedUpperCase: "InputStreaming", - generatedLowerCase: "inputStreaming" - ), - isInputStreaming: true, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let outputStreamingMethod = MethodDescriptor( - documentation: "/// Documentation for outputStreamingMethod", - name: Name( - base: "outputStreamingMethod", - generatedUpperCase: "OutputStreaming", - generatedLowerCase: "outputStreaming" - ), - isInputStreaming: false, - isOutputStreaming: true, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name( - base: "ServiceATest", - generatedUpperCase: "ServiceA", - generatedLowerCase: "serviceA" - ), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [inputStreamingMethod, outputStreamingMethod] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { - /// Documentation for inputStreamingMethod - func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - - /// Documentation for outputStreamingMethod - func outputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal func registerMethods(with router: inout GRPCCore.RPCRouter) { - router.registerHandler( - forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.inputStreaming( - request: request, - context: context - ) - } - ) - router.registerHandler( - forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.outputStreaming( - request: request, - context: context - ) - } - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol { - /// Documentation for inputStreamingMethod - func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.ServerResponse - - /// Documentation for outputStreamingMethod - func outputStreaming( - request: GRPCCore.ServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ServiceProtocol { - internal func inputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse { - let response = try await self.inputStreaming( - request: request, - context: context - ) - return GRPCCore.StreamingServerResponse(single: response) - } - - internal func outputStreaming( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse { - let response = try await self.outputStreaming( - request: GRPCCore.ServerRequest(stream: request), - context: context - ) - return response - } - } - """ - - try assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .internal - ) - } - - func testServerCodeTranslatorNoNamespaceService() throws { - let method = MethodDescriptor( - documentation: "/// Documentation for MethodA", - name: Name(base: "methodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: false, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name( - base: "ServiceATest", - generatedUpperCase: "ServiceA", - generatedLowerCase: "serviceA" - ), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [method] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal protocol ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService { - /// Documentation for MethodA - func methodA( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse - } - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal func registerMethods(with router: inout GRPCCore.RPCRouter) { - router.registerHandler( - forMethod: ServiceA.Method.MethodA.descriptor, - deserializer: GRPCProtobuf.ProtobufDeserializer(), - serializer: GRPCProtobuf.ProtobufSerializer(), - handler: { request, context in - try await self.methodA( - request: request, - context: context - ) - } - ) - } - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal protocol ServiceA_ServiceProtocol: ServiceA.StreamingServiceProtocol { - /// Documentation for MethodA - func methodA( - request: GRPCCore.ServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.ServerResponse - } - /// Partial conformance to `ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension ServiceA.ServiceProtocol { - internal func methodA( - request: GRPCCore.StreamingServerRequest, - context: GRPCCore.ServerContext - ) async throws -> GRPCCore.StreamingServerResponse { - let response = try await self.methodA( - request: GRPCCore.ServerRequest(stream: request), - context: context - ) - return GRPCCore.StreamingServerResponse(single: response) - } - } - """ - - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - accessLevel: .internal - ) + let rendered = self.render(accessLevel: .public, service: service) + #expect(rendered == expectedSwift) } - func testServerCodeTranslatorMoreServicesOrder() throws { - let serviceA = ServiceDescriptor( - documentation: "/// Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [] - ) - let serviceB = ServiceDescriptor( - documentation: "/// Documentation for ServiceB", - name: Name(base: "ServiceB", generatedUpperCase: "ServiceB", generatedLowerCase: "serviceB"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [] - ) - let expectedSwift = - """ - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {} - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public func registerMethods(with router: inout GRPCCore.RPCRouter) {} - } - /// Documentation for ServiceA - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {} - /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceA.ServiceProtocol { - } - /// Documentation for ServiceB - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceB_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {} - /// Conformance to `GRPCCore.RegistrableRPCService`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceB.StreamingServiceProtocol { - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public func registerMethods(with router: inout GRPCCore.RPCRouter) {} - } - /// Documentation for ServiceB - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public protocol NamespaceA_ServiceB_ServiceProtocol: NamespaceA_ServiceB.StreamingServiceProtocol {} - /// Partial conformance to `NamespaceA_ServiceB_StreamingServiceProtocol`. - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - extension NamespaceA_ServiceB.ServiceProtocol { - } - """ - - try self.assertServerCodeTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceA, serviceB]), - expectedSwift: expectedSwift, - accessLevel: .public - ) - } - - private func assertServerCodeTranslation( - codeGenerationRequest request: CodeGenerationRequest, - expectedSwift: String, - accessLevel: SourceGenerator.Config.AccessLevel - ) throws { + private func render( + accessLevel: AccessModifier, + service: ServiceDescriptor + ) -> String { let translator = ServerCodeTranslator() - let codeBlocks = translator.translate( - accessModifier: AccessModifier(accessLevel), - services: request.services, - serializer: request.lookupSerializer, - deserializer: request.lookupDeserializer - ) + let codeBlocks = translator.translate(accessModifier: accessLevel, services: [service]) { + "GRPCProtobuf.ProtobufSerializer<\($0)>()" + } deserializer: { + "GRPCProtobuf.ProtobufDeserializer<\($0)>()" + } + let renderer = TextBasedRenderer.default renderer.renderCodeBlocks(codeBlocks) - let contents = renderer.renderedContents() - try XCTAssertEqualWithDiff(contents, expectedSwift) + return renderer.renderedContents() } } - -#endif // os(macOS) || os(Linux)