ServerCodeTranslatorSnippetBasedTests.swift 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /*
  2. * Copyright 2023, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #if os(macOS) || os(Linux) // swift-format doesn't like canImport(Foundation.Process)
  17. import XCTest
  18. @testable import GRPCCodeGen
  19. final class ServerCodeTranslatorSnippetBasedTests: XCTestCase {
  20. typealias MethodDescriptor = GRPCCodeGen.CodeGenerationRequest.ServiceDescriptor.MethodDescriptor
  21. typealias ServiceDescriptor = GRPCCodeGen.CodeGenerationRequest.ServiceDescriptor
  22. typealias Name = GRPCCodeGen.CodeGenerationRequest.Name
  23. func testServerCodeTranslatorUnaryMethod() throws {
  24. let method = MethodDescriptor(
  25. documentation: "/// Documentation for unaryMethod",
  26. name: Name(base: "UnaryMethod", generatedUpperCase: "Unary", generatedLowerCase: "unary"),
  27. isInputStreaming: false,
  28. isOutputStreaming: false,
  29. inputType: "NamespaceA_ServiceARequest",
  30. outputType: "NamespaceA_ServiceAResponse"
  31. )
  32. let service = ServiceDescriptor(
  33. documentation: "/// Documentation for ServiceA",
  34. name: Name(
  35. base: "AlongNameForServiceA",
  36. generatedUpperCase: "ServiceA",
  37. generatedLowerCase: "serviceA"
  38. ),
  39. namespace: Name(
  40. base: "namespaceA",
  41. generatedUpperCase: "NamespaceA",
  42. generatedLowerCase: "namespaceA"
  43. ),
  44. methods: [method]
  45. )
  46. let expectedSwift =
  47. """
  48. /// Documentation for ServiceA
  49. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  50. public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  51. /// Documentation for unaryMethod
  52. func unary(
  53. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  54. context: GRPCCore.ServerContext
  55. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  56. }
  57. /// Conformance to `GRPCCore.RegistrableRPCService`.
  58. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  59. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  60. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  61. public func registerMethods(with router: inout GRPCCore.RPCRouter) {
  62. router.registerHandler(
  63. forMethod: NamespaceA_ServiceA.Method.Unary.descriptor,
  64. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  65. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  66. handler: { request, context in
  67. try await self.unary(
  68. request: request,
  69. context: context
  70. )
  71. }
  72. )
  73. }
  74. }
  75. /// Documentation for ServiceA
  76. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  77. public protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  78. /// Documentation for unaryMethod
  79. func unary(
  80. request: GRPCCore.ServerRequest<NamespaceA_ServiceARequest>,
  81. context: GRPCCore.ServerContext
  82. ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
  83. }
  84. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  85. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  86. extension NamespaceA_ServiceA.ServiceProtocol {
  87. public func unary(
  88. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  89. context: GRPCCore.ServerContext
  90. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  91. let response = try await self.unary(
  92. request: GRPCCore.ServerRequest(stream: request),
  93. context: context
  94. )
  95. return GRPCCore.StreamingServerResponse(single: response)
  96. }
  97. }
  98. """
  99. try self.assertServerCodeTranslation(
  100. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  101. expectedSwift: expectedSwift,
  102. accessLevel: .public
  103. )
  104. }
  105. func testServerCodeTranslatorInputStreamingMethod() throws {
  106. let method = MethodDescriptor(
  107. documentation: "/// Documentation for inputStreamingMethod",
  108. name: Name(
  109. base: "InputStreamingMethod",
  110. generatedUpperCase: "InputStreaming",
  111. generatedLowerCase: "inputStreaming"
  112. ),
  113. isInputStreaming: true,
  114. isOutputStreaming: false,
  115. inputType: "NamespaceA_ServiceARequest",
  116. outputType: "NamespaceA_ServiceAResponse"
  117. )
  118. let service = ServiceDescriptor(
  119. documentation: "/// Documentation for ServiceA",
  120. name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"),
  121. namespace: Name(
  122. base: "namespaceA",
  123. generatedUpperCase: "NamespaceA",
  124. generatedLowerCase: "namespaceA"
  125. ),
  126. methods: [method]
  127. )
  128. let expectedSwift =
  129. """
  130. /// Documentation for ServiceA
  131. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  132. package protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  133. /// Documentation for inputStreamingMethod
  134. func inputStreaming(
  135. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  136. context: GRPCCore.ServerContext
  137. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  138. }
  139. /// Conformance to `GRPCCore.RegistrableRPCService`.
  140. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  141. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  142. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  143. package func registerMethods(with router: inout GRPCCore.RPCRouter) {
  144. router.registerHandler(
  145. forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor,
  146. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  147. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  148. handler: { request, context in
  149. try await self.inputStreaming(
  150. request: request,
  151. context: context
  152. )
  153. }
  154. )
  155. }
  156. }
  157. /// Documentation for ServiceA
  158. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  159. package protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  160. /// Documentation for inputStreamingMethod
  161. func inputStreaming(
  162. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  163. context: GRPCCore.ServerContext
  164. ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
  165. }
  166. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  167. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  168. extension NamespaceA_ServiceA.ServiceProtocol {
  169. package func inputStreaming(
  170. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  171. context: GRPCCore.ServerContext
  172. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  173. let response = try await self.inputStreaming(
  174. request: request,
  175. context: context
  176. )
  177. return GRPCCore.StreamingServerResponse(single: response)
  178. }
  179. }
  180. """
  181. try self.assertServerCodeTranslation(
  182. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  183. expectedSwift: expectedSwift,
  184. accessLevel: .package
  185. )
  186. }
  187. func testServerCodeTranslatorOutputStreamingMethod() throws {
  188. let method = MethodDescriptor(
  189. documentation: "/// Documentation for outputStreamingMethod",
  190. name: Name(
  191. base: "OutputStreamingMethod",
  192. generatedUpperCase: "OutputStreaming",
  193. generatedLowerCase: "outputStreaming"
  194. ),
  195. isInputStreaming: false,
  196. isOutputStreaming: true,
  197. inputType: "NamespaceA_ServiceARequest",
  198. outputType: "NamespaceA_ServiceAResponse"
  199. )
  200. let service = ServiceDescriptor(
  201. documentation: "/// Documentation for ServiceA",
  202. name: Name(
  203. base: "ServiceATest",
  204. generatedUpperCase: "ServiceA",
  205. generatedLowerCase: "serviceA"
  206. ),
  207. namespace: Name(
  208. base: "namespaceA",
  209. generatedUpperCase: "NamespaceA",
  210. generatedLowerCase: "namespaceA"
  211. ),
  212. methods: [method]
  213. )
  214. let expectedSwift =
  215. """
  216. /// Documentation for ServiceA
  217. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  218. public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  219. /// Documentation for outputStreamingMethod
  220. func outputStreaming(
  221. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  222. context: GRPCCore.ServerContext
  223. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  224. }
  225. /// Conformance to `GRPCCore.RegistrableRPCService`.
  226. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  227. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  228. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  229. public func registerMethods(with router: inout GRPCCore.RPCRouter) {
  230. router.registerHandler(
  231. forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor,
  232. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  233. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  234. handler: { request, context in
  235. try await self.outputStreaming(
  236. request: request,
  237. context: context
  238. )
  239. }
  240. )
  241. }
  242. }
  243. /// Documentation for ServiceA
  244. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  245. public protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  246. /// Documentation for outputStreamingMethod
  247. func outputStreaming(
  248. request: GRPCCore.ServerRequest<NamespaceA_ServiceARequest>,
  249. context: GRPCCore.ServerContext
  250. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  251. }
  252. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  253. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  254. extension NamespaceA_ServiceA.ServiceProtocol {
  255. public func outputStreaming(
  256. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  257. context: GRPCCore.ServerContext
  258. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  259. let response = try await self.outputStreaming(
  260. request: GRPCCore.ServerRequest(stream: request),
  261. context: context
  262. )
  263. return response
  264. }
  265. }
  266. """
  267. try self.assertServerCodeTranslation(
  268. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  269. expectedSwift: expectedSwift,
  270. accessLevel: .public
  271. )
  272. }
  273. func testServerCodeTranslatorBidirectionalStreamingMethod() throws {
  274. let method = MethodDescriptor(
  275. documentation: "/// Documentation for bidirectionalStreamingMethod",
  276. name: Name(
  277. base: "BidirectionalStreamingMethod",
  278. generatedUpperCase: "BidirectionalStreaming",
  279. generatedLowerCase: "bidirectionalStreaming"
  280. ),
  281. isInputStreaming: true,
  282. isOutputStreaming: true,
  283. inputType: "NamespaceA_ServiceARequest",
  284. outputType: "NamespaceA_ServiceAResponse"
  285. )
  286. let service = ServiceDescriptor(
  287. documentation: "/// Documentation for ServiceA",
  288. name: Name(
  289. base: "ServiceATest",
  290. generatedUpperCase: "ServiceA",
  291. generatedLowerCase: "serviceA"
  292. ),
  293. namespace: Name(
  294. base: "namespaceA",
  295. generatedUpperCase: "NamespaceA",
  296. generatedLowerCase: "namespaceA"
  297. ),
  298. methods: [method]
  299. )
  300. let expectedSwift =
  301. """
  302. /// Documentation for ServiceA
  303. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  304. package protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  305. /// Documentation for bidirectionalStreamingMethod
  306. func bidirectionalStreaming(
  307. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  308. context: GRPCCore.ServerContext
  309. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  310. }
  311. /// Conformance to `GRPCCore.RegistrableRPCService`.
  312. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  313. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  314. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  315. package func registerMethods(with router: inout GRPCCore.RPCRouter) {
  316. router.registerHandler(
  317. forMethod: NamespaceA_ServiceA.Method.BidirectionalStreaming.descriptor,
  318. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  319. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  320. handler: { request, context in
  321. try await self.bidirectionalStreaming(
  322. request: request,
  323. context: context
  324. )
  325. }
  326. )
  327. }
  328. }
  329. /// Documentation for ServiceA
  330. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  331. package protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  332. /// Documentation for bidirectionalStreamingMethod
  333. func bidirectionalStreaming(
  334. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  335. context: GRPCCore.ServerContext
  336. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  337. }
  338. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  339. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  340. extension NamespaceA_ServiceA.ServiceProtocol {
  341. }
  342. """
  343. try self.assertServerCodeTranslation(
  344. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  345. expectedSwift: expectedSwift,
  346. accessLevel: .package
  347. )
  348. }
  349. func testServerCodeTranslatorMultipleMethods() throws {
  350. let inputStreamingMethod = MethodDescriptor(
  351. documentation: "/// Documentation for inputStreamingMethod",
  352. name: Name(
  353. base: "InputStreamingMethod",
  354. generatedUpperCase: "InputStreaming",
  355. generatedLowerCase: "inputStreaming"
  356. ),
  357. isInputStreaming: true,
  358. isOutputStreaming: false,
  359. inputType: "NamespaceA_ServiceARequest",
  360. outputType: "NamespaceA_ServiceAResponse"
  361. )
  362. let outputStreamingMethod = MethodDescriptor(
  363. documentation: "/// Documentation for outputStreamingMethod",
  364. name: Name(
  365. base: "outputStreamingMethod",
  366. generatedUpperCase: "OutputStreaming",
  367. generatedLowerCase: "outputStreaming"
  368. ),
  369. isInputStreaming: false,
  370. isOutputStreaming: true,
  371. inputType: "NamespaceA_ServiceARequest",
  372. outputType: "NamespaceA_ServiceAResponse"
  373. )
  374. let service = ServiceDescriptor(
  375. documentation: "/// Documentation for ServiceA",
  376. name: Name(
  377. base: "ServiceATest",
  378. generatedUpperCase: "ServiceA",
  379. generatedLowerCase: "serviceA"
  380. ),
  381. namespace: Name(
  382. base: "namespaceA",
  383. generatedUpperCase: "NamespaceA",
  384. generatedLowerCase: "namespaceA"
  385. ),
  386. methods: [inputStreamingMethod, outputStreamingMethod]
  387. )
  388. let expectedSwift =
  389. """
  390. /// Documentation for ServiceA
  391. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  392. internal protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  393. /// Documentation for inputStreamingMethod
  394. func inputStreaming(
  395. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  396. context: GRPCCore.ServerContext
  397. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  398. /// Documentation for outputStreamingMethod
  399. func outputStreaming(
  400. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  401. context: GRPCCore.ServerContext
  402. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  403. }
  404. /// Conformance to `GRPCCore.RegistrableRPCService`.
  405. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  406. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  407. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  408. internal func registerMethods(with router: inout GRPCCore.RPCRouter) {
  409. router.registerHandler(
  410. forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor,
  411. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  412. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  413. handler: { request, context in
  414. try await self.inputStreaming(
  415. request: request,
  416. context: context
  417. )
  418. }
  419. )
  420. router.registerHandler(
  421. forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor,
  422. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  423. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  424. handler: { request, context in
  425. try await self.outputStreaming(
  426. request: request,
  427. context: context
  428. )
  429. }
  430. )
  431. }
  432. }
  433. /// Documentation for ServiceA
  434. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  435. internal protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  436. /// Documentation for inputStreamingMethod
  437. func inputStreaming(
  438. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  439. context: GRPCCore.ServerContext
  440. ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
  441. /// Documentation for outputStreamingMethod
  442. func outputStreaming(
  443. request: GRPCCore.ServerRequest<NamespaceA_ServiceARequest>,
  444. context: GRPCCore.ServerContext
  445. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  446. }
  447. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  448. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  449. extension NamespaceA_ServiceA.ServiceProtocol {
  450. internal func inputStreaming(
  451. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  452. context: GRPCCore.ServerContext
  453. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  454. let response = try await self.inputStreaming(
  455. request: request,
  456. context: context
  457. )
  458. return GRPCCore.StreamingServerResponse(single: response)
  459. }
  460. internal func outputStreaming(
  461. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  462. context: GRPCCore.ServerContext
  463. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  464. let response = try await self.outputStreaming(
  465. request: GRPCCore.ServerRequest(stream: request),
  466. context: context
  467. )
  468. return response
  469. }
  470. }
  471. """
  472. try assertServerCodeTranslation(
  473. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  474. expectedSwift: expectedSwift,
  475. accessLevel: .internal
  476. )
  477. }
  478. func testServerCodeTranslatorNoNamespaceService() throws {
  479. let method = MethodDescriptor(
  480. documentation: "/// Documentation for MethodA",
  481. name: Name(base: "methodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"),
  482. isInputStreaming: false,
  483. isOutputStreaming: false,
  484. inputType: "NamespaceA_ServiceARequest",
  485. outputType: "NamespaceA_ServiceAResponse"
  486. )
  487. let service = ServiceDescriptor(
  488. documentation: "/// Documentation for ServiceA",
  489. name: Name(
  490. base: "ServiceATest",
  491. generatedUpperCase: "ServiceA",
  492. generatedLowerCase: "serviceA"
  493. ),
  494. namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""),
  495. methods: [method]
  496. )
  497. let expectedSwift =
  498. """
  499. /// Documentation for ServiceA
  500. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  501. internal protocol ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  502. /// Documentation for MethodA
  503. func methodA(
  504. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  505. context: GRPCCore.ServerContext
  506. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse>
  507. }
  508. /// Conformance to `GRPCCore.RegistrableRPCService`.
  509. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  510. extension ServiceA.StreamingServiceProtocol {
  511. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  512. internal func registerMethods(with router: inout GRPCCore.RPCRouter) {
  513. router.registerHandler(
  514. forMethod: ServiceA.Method.MethodA.descriptor,
  515. deserializer: GRPCProtobuf.ProtobufDeserializer<NamespaceA_ServiceARequest>(),
  516. serializer: GRPCProtobuf.ProtobufSerializer<NamespaceA_ServiceAResponse>(),
  517. handler: { request, context in
  518. try await self.methodA(
  519. request: request,
  520. context: context
  521. )
  522. }
  523. )
  524. }
  525. }
  526. /// Documentation for ServiceA
  527. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  528. internal protocol ServiceA_ServiceProtocol: ServiceA.StreamingServiceProtocol {
  529. /// Documentation for MethodA
  530. func methodA(
  531. request: GRPCCore.ServerRequest<NamespaceA_ServiceARequest>,
  532. context: GRPCCore.ServerContext
  533. ) async throws -> GRPCCore.ServerResponse<NamespaceA_ServiceAResponse>
  534. }
  535. /// Partial conformance to `ServiceA_StreamingServiceProtocol`.
  536. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  537. extension ServiceA.ServiceProtocol {
  538. internal func methodA(
  539. request: GRPCCore.StreamingServerRequest<NamespaceA_ServiceARequest>,
  540. context: GRPCCore.ServerContext
  541. ) async throws -> GRPCCore.StreamingServerResponse<NamespaceA_ServiceAResponse> {
  542. let response = try await self.methodA(
  543. request: GRPCCore.ServerRequest(stream: request),
  544. context: context
  545. )
  546. return GRPCCore.StreamingServerResponse(single: response)
  547. }
  548. }
  549. """
  550. try self.assertServerCodeTranslation(
  551. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  552. expectedSwift: expectedSwift,
  553. accessLevel: .internal
  554. )
  555. }
  556. func testServerCodeTranslatorMoreServicesOrder() throws {
  557. let serviceA = ServiceDescriptor(
  558. documentation: "/// Documentation for ServiceA",
  559. name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"),
  560. namespace: Name(
  561. base: "namespaceA",
  562. generatedUpperCase: "NamespaceA",
  563. generatedLowerCase: "namespaceA"
  564. ),
  565. methods: []
  566. )
  567. let serviceB = ServiceDescriptor(
  568. documentation: "/// Documentation for ServiceB",
  569. name: Name(base: "ServiceB", generatedUpperCase: "ServiceB", generatedLowerCase: "serviceB"),
  570. namespace: Name(
  571. base: "namespaceA",
  572. generatedUpperCase: "NamespaceA",
  573. generatedLowerCase: "namespaceA"
  574. ),
  575. methods: []
  576. )
  577. let expectedSwift =
  578. """
  579. /// Documentation for ServiceA
  580. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  581. public protocol NamespaceA_ServiceA_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {}
  582. /// Conformance to `GRPCCore.RegistrableRPCService`.
  583. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  584. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  585. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  586. public func registerMethods(with router: inout GRPCCore.RPCRouter) {}
  587. }
  588. /// Documentation for ServiceA
  589. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  590. public protocol NamespaceA_ServiceA_ServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {}
  591. /// Partial conformance to `NamespaceA_ServiceA_StreamingServiceProtocol`.
  592. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  593. extension NamespaceA_ServiceA.ServiceProtocol {
  594. }
  595. /// Documentation for ServiceB
  596. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  597. public protocol NamespaceA_ServiceB_StreamingServiceProtocol: GRPCCore.RegistrableRPCService {}
  598. /// Conformance to `GRPCCore.RegistrableRPCService`.
  599. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  600. extension NamespaceA_ServiceB.StreamingServiceProtocol {
  601. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  602. public func registerMethods(with router: inout GRPCCore.RPCRouter) {}
  603. }
  604. /// Documentation for ServiceB
  605. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  606. public protocol NamespaceA_ServiceB_ServiceProtocol: NamespaceA_ServiceB.StreamingServiceProtocol {}
  607. /// Partial conformance to `NamespaceA_ServiceB_StreamingServiceProtocol`.
  608. @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
  609. extension NamespaceA_ServiceB.ServiceProtocol {
  610. }
  611. """
  612. try self.assertServerCodeTranslation(
  613. codeGenerationRequest: makeCodeGenerationRequest(services: [serviceA, serviceB]),
  614. expectedSwift: expectedSwift,
  615. accessLevel: .public
  616. )
  617. }
  618. private func assertServerCodeTranslation(
  619. codeGenerationRequest: CodeGenerationRequest,
  620. expectedSwift: String,
  621. accessLevel: SourceGenerator.Config.AccessLevel
  622. ) throws {
  623. let translator = ServerCodeTranslator(accessLevel: accessLevel)
  624. let codeBlocks = try translator.translate(from: codeGenerationRequest)
  625. let renderer = TextBasedRenderer.default
  626. renderer.renderCodeBlocks(codeBlocks)
  627. let contents = renderer.renderedContents()
  628. try XCTAssertEqualWithDiff(contents, expectedSwift)
  629. }
  630. }
  631. #endif // os(macOS) || os(Linux)