Browse Source

Simplify client/server translator tests (#2129)

Motivation:

The client and server translator tests have a lot of repetition. Now
that they are based on structured swift extension, which is tested
separately, the tests can be much briefer as the translators just glue a
few bit together.

Modifications:

- Remove a bunch of translator tests as they are already covered by
lower level tests

Result:

Less maintenance burden
George Barnett 1 year ago
parent
commit
8bc2a25602

+ 23 - 694
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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodA(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceAResponse>(),
-                  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<Result>(
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<NamespaceA_ServiceARequest>) async throws -> Void,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>(
-                  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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodA(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceAResponse>(),
-                  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<Result>(
-              _ message: NamespaceA_ServiceARequest,
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.ClientRequest<NamespaceA_ServiceARequest>(
-                  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<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodA(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceAResponse>(),
-                  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<Result>(
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<NamespaceA_ServiceARequest>) async throws -> Void,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>(
-                  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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable
-
-          /// Documentation for MethodB
-          func methodB<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodA(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceAResponse>(),
-                  options: options,
-                  onResponse: handleResponse
-              )
-          }
-
-          package func methodB<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodB(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceAResponse>(),
-                  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<Result>(
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<NamespaceA_ServiceARequest>) async throws -> Void,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>(
-                  metadata: metadata,
-                  producer: producer
-              )
-              return try await self.methodA(
-                  request: request,
-                  options: options,
-                  onResponse: handleResponse
-              )
-          }
-
-          /// Documentation for MethodB
-          package func methodB<Result>(
-              _ message: NamespaceA_ServiceARequest,
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) async throws -> Result
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.ClientRequest<NamespaceA_ServiceARequest>(
-                  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<Result>(
-              request: GRPCCore.StreamingClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.ClientRequest<NamespaceA_ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<NamespaceA_ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<NamespaceA_ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<NamespaceA_ServiceAResponse>) 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<Result>(
-              request: GRPCCore.ClientRequest<ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<ServiceAResponse>,
-              options: GRPCCore.CallOptions,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<ServiceAResponse>) 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<Result>(
-              request: GRPCCore.ClientRequest<ServiceARequest>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              try await self.methodA(
-                  request: request,
-                  serializer: GRPCProtobuf.ProtobufSerializer<ServiceARequest>(),
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<ServiceAResponse>(),
-                  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<Result>(
-              _ message: ServiceARequest,
-              metadata: GRPCCore.Metadata = [:],
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<ServiceAResponse>) async throws -> Result = { response in
-                  try response.message
-              }
-          ) async throws -> Result where Result: Sendable {
-              let request = GRPCCore.ClientRequest<ServiceARequest>(
-                  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<Result>(
-              request: GRPCCore.ClientRequest<ServiceARequest>,
-              serializer: some GRPCCore.MessageSerializer<ServiceARequest>,
-              deserializer: some GRPCCore.MessageDeserializer<ServiceAResponse>,
-              options: GRPCCore.CallOptions = .defaults,
-              onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<ServiceAResponse>) 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)

+ 21 - 555
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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
-              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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
-              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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-
-          /// Documentation for outputStreamingMethod
-          func outputStreaming(
-              request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  handler: { request, context in
-                      try await self.inputStreaming(
-                          request: request,
-                          context: context
-                      )
-                  }
-              )
-              router.registerHandler(
-                  forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor,
-                  deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
-
-          /// Documentation for outputStreamingMethod
-          func outputStreaming(
-              request: GRPCCore.ServerRequest<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
-              let response = try await self.inputStreaming(
-                  request: request,
-                  context: context
-              )
-              return GRPCCore.StreamingServerResponse(single: response)
-          }
-
-          internal func outputStreaming(
-              request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
-              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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>(),
-                  serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
-                  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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
-      }
-      /// 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<NamespaceA_ServiceARequest>,
-              context: GRPCCore.ServerContext
-          ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
-              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)