ServerCodeTranslatorSnippetBasedTests.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  50. public protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  51. /// Documentation for unaryMethod
  52. func unary(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.Unary.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.Unary.Output>
  53. }
  54. /// Conformance to `GRPCCore.RegistrableRPCService`.
  55. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  56. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  57. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  58. public func registerMethods(with router: inout GRPCCore.RPCRouter) {
  59. router.registerHandler(
  60. forMethod: NamespaceA_ServiceA.Method.Unary.descriptor,
  61. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.Unary.Input>(),
  62. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.Unary.Output>(),
  63. handler: { request in
  64. try await self.unary(request: request)
  65. }
  66. )
  67. }
  68. }
  69. /// Documentation for ServiceA
  70. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  71. public protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  72. /// Documentation for unaryMethod
  73. func unary(request: ServerRequest.Single<NamespaceA_ServiceA.Method.Unary.Input>) async throws -> ServerResponse.Single<NamespaceA_ServiceA.Method.Unary.Output>
  74. }
  75. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  76. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  77. extension NamespaceA_ServiceA.ServiceProtocol {
  78. public func unary(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.Unary.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.Unary.Output> {
  79. let response = try await self.unary(request: ServerRequest.Single(stream: request))
  80. return ServerResponse.Stream(single: response)
  81. }
  82. }
  83. """
  84. try self.assertServerCodeTranslation(
  85. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  86. expectedSwift: expectedSwift,
  87. accessLevel: .public
  88. )
  89. }
  90. func testServerCodeTranslatorInputStreamingMethod() throws {
  91. let method = MethodDescriptor(
  92. documentation: "/// Documentation for inputStreamingMethod",
  93. name: Name(
  94. base: "InputStreamingMethod",
  95. generatedUpperCase: "InputStreaming",
  96. generatedLowerCase: "inputStreaming"
  97. ),
  98. isInputStreaming: true,
  99. isOutputStreaming: false,
  100. inputType: "NamespaceA_ServiceARequest",
  101. outputType: "NamespaceA_ServiceAResponse"
  102. )
  103. let service = ServiceDescriptor(
  104. documentation: "/// Documentation for ServiceA",
  105. name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"),
  106. namespace: Name(
  107. base: "namespaceA",
  108. generatedUpperCase: "NamespaceA",
  109. generatedLowerCase: "namespaceA"
  110. ),
  111. methods: [method]
  112. )
  113. let expectedSwift =
  114. """
  115. /// Documentation for ServiceA
  116. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  117. package protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  118. /// Documentation for inputStreamingMethod
  119. func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.InputStreaming.Output>
  120. }
  121. /// Conformance to `GRPCCore.RegistrableRPCService`.
  122. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  123. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  124. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  125. package func registerMethods(with router: inout GRPCCore.RPCRouter) {
  126. router.registerHandler(
  127. forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor,
  128. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.InputStreaming.Input>(),
  129. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.InputStreaming.Output>(),
  130. handler: { request in
  131. try await self.inputStreaming(request: request)
  132. }
  133. )
  134. }
  135. }
  136. /// Documentation for ServiceA
  137. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  138. package protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  139. /// Documentation for inputStreamingMethod
  140. func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Single<NamespaceA_ServiceA.Method.InputStreaming.Output>
  141. }
  142. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  143. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  144. extension NamespaceA_ServiceA.ServiceProtocol {
  145. package func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.InputStreaming.Output> {
  146. let response = try await self.inputStreaming(request: request)
  147. return ServerResponse.Stream(single: response)
  148. }
  149. }
  150. """
  151. try self.assertServerCodeTranslation(
  152. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  153. expectedSwift: expectedSwift,
  154. accessLevel: .package
  155. )
  156. }
  157. func testServerCodeTranslatorOutputStreamingMethod() throws {
  158. let method = MethodDescriptor(
  159. documentation: "/// Documentation for outputStreamingMethod",
  160. name: Name(
  161. base: "OutputStreamingMethod",
  162. generatedUpperCase: "OutputStreaming",
  163. generatedLowerCase: "outputStreaming"
  164. ),
  165. isInputStreaming: false,
  166. isOutputStreaming: true,
  167. inputType: "NamespaceA_ServiceARequest",
  168. outputType: "NamespaceA_ServiceAResponse"
  169. )
  170. let service = ServiceDescriptor(
  171. documentation: "/// Documentation for ServiceA",
  172. name: Name(
  173. base: "ServiceATest",
  174. generatedUpperCase: "ServiceA",
  175. generatedLowerCase: "serviceA"
  176. ),
  177. namespace: Name(
  178. base: "namespaceA",
  179. generatedUpperCase: "NamespaceA",
  180. generatedLowerCase: "namespaceA"
  181. ),
  182. methods: [method]
  183. )
  184. let expectedSwift =
  185. """
  186. /// Documentation for ServiceA
  187. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  188. public protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  189. /// Documentation for outputStreamingMethod
  190. func outputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output>
  191. }
  192. /// Conformance to `GRPCCore.RegistrableRPCService`.
  193. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  194. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  195. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  196. public func registerMethods(with router: inout GRPCCore.RPCRouter) {
  197. router.registerHandler(
  198. forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor,
  199. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.OutputStreaming.Input>(),
  200. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.OutputStreaming.Output>(),
  201. handler: { request in
  202. try await self.outputStreaming(request: request)
  203. }
  204. )
  205. }
  206. }
  207. /// Documentation for ServiceA
  208. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  209. public protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  210. /// Documentation for outputStreamingMethod
  211. func outputStreaming(request: ServerRequest.Single<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output>
  212. }
  213. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  214. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  215. extension NamespaceA_ServiceA.ServiceProtocol {
  216. public func outputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output> {
  217. let response = try await self.outputStreaming(request: ServerRequest.Single(stream: request))
  218. return response
  219. }
  220. }
  221. """
  222. try self.assertServerCodeTranslation(
  223. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  224. expectedSwift: expectedSwift,
  225. accessLevel: .public
  226. )
  227. }
  228. func testServerCodeTranslatorBidirectionalStreamingMethod() throws {
  229. let method = MethodDescriptor(
  230. documentation: "/// Documentation for bidirectionalStreamingMethod",
  231. name: Name(
  232. base: "BidirectionalStreamingMethod",
  233. generatedUpperCase: "BidirectionalStreaming",
  234. generatedLowerCase: "bidirectionalStreaming"
  235. ),
  236. isInputStreaming: true,
  237. isOutputStreaming: true,
  238. inputType: "NamespaceA_ServiceARequest",
  239. outputType: "NamespaceA_ServiceAResponse"
  240. )
  241. let service = ServiceDescriptor(
  242. documentation: "/// Documentation for ServiceA",
  243. name: Name(
  244. base: "ServiceATest",
  245. generatedUpperCase: "ServiceA",
  246. generatedLowerCase: "serviceA"
  247. ),
  248. namespace: Name(
  249. base: "namespaceA",
  250. generatedUpperCase: "NamespaceA",
  251. generatedLowerCase: "namespaceA"
  252. ),
  253. methods: [method]
  254. )
  255. let expectedSwift =
  256. """
  257. /// Documentation for ServiceA
  258. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  259. package protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  260. /// Documentation for bidirectionalStreamingMethod
  261. func bidirectionalStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.BidirectionalStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.BidirectionalStreaming.Output>
  262. }
  263. /// Conformance to `GRPCCore.RegistrableRPCService`.
  264. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  265. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  266. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  267. package func registerMethods(with router: inout GRPCCore.RPCRouter) {
  268. router.registerHandler(
  269. forMethod: NamespaceA_ServiceA.Method.BidirectionalStreaming.descriptor,
  270. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.BidirectionalStreaming.Input>(),
  271. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.BidirectionalStreaming.Output>(),
  272. handler: { request in
  273. try await self.bidirectionalStreaming(request: request)
  274. }
  275. )
  276. }
  277. }
  278. /// Documentation for ServiceA
  279. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  280. package protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  281. /// Documentation for bidirectionalStreamingMethod
  282. func bidirectionalStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.BidirectionalStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.BidirectionalStreaming.Output>
  283. }
  284. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  285. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  286. extension NamespaceA_ServiceA.ServiceProtocol {
  287. }
  288. """
  289. try self.assertServerCodeTranslation(
  290. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  291. expectedSwift: expectedSwift,
  292. accessLevel: .package
  293. )
  294. }
  295. func testServerCodeTranslatorMultipleMethods() throws {
  296. let inputStreamingMethod = MethodDescriptor(
  297. documentation: "/// Documentation for inputStreamingMethod",
  298. name: Name(
  299. base: "InputStreamingMethod",
  300. generatedUpperCase: "InputStreaming",
  301. generatedLowerCase: "inputStreaming"
  302. ),
  303. isInputStreaming: true,
  304. isOutputStreaming: false,
  305. inputType: "NamespaceA_ServiceARequest",
  306. outputType: "NamespaceA_ServiceAResponse"
  307. )
  308. let outputStreamingMethod = MethodDescriptor(
  309. documentation: "/// Documentation for outputStreamingMethod",
  310. name: Name(
  311. base: "outputStreamingMethod",
  312. generatedUpperCase: "OutputStreaming",
  313. generatedLowerCase: "outputStreaming"
  314. ),
  315. isInputStreaming: false,
  316. isOutputStreaming: true,
  317. inputType: "NamespaceA_ServiceARequest",
  318. outputType: "NamespaceA_ServiceAResponse"
  319. )
  320. let service = ServiceDescriptor(
  321. documentation: "/// Documentation for ServiceA",
  322. name: Name(
  323. base: "ServiceATest",
  324. generatedUpperCase: "ServiceA",
  325. generatedLowerCase: "serviceA"
  326. ),
  327. namespace: Name(
  328. base: "namespaceA",
  329. generatedUpperCase: "NamespaceA",
  330. generatedLowerCase: "namespaceA"
  331. ),
  332. methods: [inputStreamingMethod, outputStreamingMethod]
  333. )
  334. let expectedSwift =
  335. """
  336. /// Documentation for ServiceA
  337. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  338. internal protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  339. /// Documentation for inputStreamingMethod
  340. func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.InputStreaming.Output>
  341. /// Documentation for outputStreamingMethod
  342. func outputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output>
  343. }
  344. /// Conformance to `GRPCCore.RegistrableRPCService`.
  345. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  346. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  347. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  348. internal func registerMethods(with router: inout GRPCCore.RPCRouter) {
  349. router.registerHandler(
  350. forMethod: NamespaceA_ServiceA.Method.InputStreaming.descriptor,
  351. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.InputStreaming.Input>(),
  352. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.InputStreaming.Output>(),
  353. handler: { request in
  354. try await self.inputStreaming(request: request)
  355. }
  356. )
  357. router.registerHandler(
  358. forMethod: NamespaceA_ServiceA.Method.OutputStreaming.descriptor,
  359. deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.OutputStreaming.Input>(),
  360. serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.OutputStreaming.Output>(),
  361. handler: { request in
  362. try await self.outputStreaming(request: request)
  363. }
  364. )
  365. }
  366. }
  367. /// Documentation for ServiceA
  368. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  369. internal protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {
  370. /// Documentation for inputStreamingMethod
  371. func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Single<NamespaceA_ServiceA.Method.InputStreaming.Output>
  372. /// Documentation for outputStreamingMethod
  373. func outputStreaming(request: ServerRequest.Single<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output>
  374. }
  375. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  376. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  377. extension NamespaceA_ServiceA.ServiceProtocol {
  378. internal func inputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.InputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.InputStreaming.Output> {
  379. let response = try await self.inputStreaming(request: request)
  380. return ServerResponse.Stream(single: response)
  381. }
  382. internal func outputStreaming(request: ServerRequest.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Input>) async throws -> ServerResponse.Stream<NamespaceA_ServiceA.Method.OutputStreaming.Output> {
  383. let response = try await self.outputStreaming(request: ServerRequest.Single(stream: request))
  384. return response
  385. }
  386. }
  387. """
  388. try assertServerCodeTranslation(
  389. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  390. expectedSwift: expectedSwift,
  391. accessLevel: .internal
  392. )
  393. }
  394. func testServerCodeTranslatorNoNamespaceService() throws {
  395. let method = MethodDescriptor(
  396. documentation: "/// Documentation for MethodA",
  397. name: Name(base: "methodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"),
  398. isInputStreaming: false,
  399. isOutputStreaming: false,
  400. inputType: "NamespaceA_ServiceARequest",
  401. outputType: "NamespaceA_ServiceAResponse"
  402. )
  403. let service = ServiceDescriptor(
  404. documentation: "/// Documentation for ServiceA",
  405. name: Name(
  406. base: "ServiceATest",
  407. generatedUpperCase: "ServiceA",
  408. generatedLowerCase: "serviceA"
  409. ),
  410. namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""),
  411. methods: [method]
  412. )
  413. let expectedSwift =
  414. """
  415. /// Documentation for ServiceA
  416. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  417. internal protocol ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {
  418. /// Documentation for MethodA
  419. func methodA(request: ServerRequest.Stream<ServiceA.Method.MethodA.Input>) async throws -> ServerResponse.Stream<ServiceA.Method.MethodA.Output>
  420. }
  421. /// Conformance to `GRPCCore.RegistrableRPCService`.
  422. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  423. extension ServiceA.StreamingServiceProtocol {
  424. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  425. internal func registerMethods(with router: inout GRPCCore.RPCRouter) {
  426. router.registerHandler(
  427. forMethod: ServiceA.Method.MethodA.descriptor,
  428. deserializer: ProtobufDeserializer<ServiceA.Method.MethodA.Input>(),
  429. serializer: ProtobufSerializer<ServiceA.Method.MethodA.Output>(),
  430. handler: { request in
  431. try await self.methodA(request: request)
  432. }
  433. )
  434. }
  435. }
  436. /// Documentation for ServiceA
  437. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  438. internal protocol ServiceAServiceProtocol: ServiceA.StreamingServiceProtocol {
  439. /// Documentation for MethodA
  440. func methodA(request: ServerRequest.Single<ServiceA.Method.MethodA.Input>) async throws -> ServerResponse.Single<ServiceA.Method.MethodA.Output>
  441. }
  442. /// Partial conformance to `ServiceAStreamingServiceProtocol`.
  443. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  444. extension ServiceA.ServiceProtocol {
  445. internal func methodA(request: ServerRequest.Stream<ServiceA.Method.MethodA.Input>) async throws -> ServerResponse.Stream<ServiceA.Method.MethodA.Output> {
  446. let response = try await self.methodA(request: ServerRequest.Single(stream: request))
  447. return ServerResponse.Stream(single: response)
  448. }
  449. }
  450. """
  451. try self.assertServerCodeTranslation(
  452. codeGenerationRequest: makeCodeGenerationRequest(services: [service]),
  453. expectedSwift: expectedSwift,
  454. accessLevel: .internal
  455. )
  456. }
  457. func testServerCodeTranslatorMoreServicesOrder() throws {
  458. let serviceA = ServiceDescriptor(
  459. documentation: "/// Documentation for ServiceA",
  460. name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"),
  461. namespace: Name(
  462. base: "namespaceA",
  463. generatedUpperCase: "NamespaceA",
  464. generatedLowerCase: "namespaceA"
  465. ),
  466. methods: []
  467. )
  468. let serviceB = ServiceDescriptor(
  469. documentation: "/// Documentation for ServiceB",
  470. name: Name(base: "ServiceB", generatedUpperCase: "ServiceB", generatedLowerCase: "serviceB"),
  471. namespace: Name(
  472. base: "namespaceA",
  473. generatedUpperCase: "NamespaceA",
  474. generatedLowerCase: "namespaceA"
  475. ),
  476. methods: []
  477. )
  478. let expectedSwift =
  479. """
  480. /// Documentation for ServiceA
  481. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  482. public protocol NamespaceA_ServiceAStreamingServiceProtocol: GRPCCore.RegistrableRPCService {}
  483. /// Conformance to `GRPCCore.RegistrableRPCService`.
  484. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  485. extension NamespaceA_ServiceA.StreamingServiceProtocol {
  486. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  487. public func registerMethods(with router: inout GRPCCore.RPCRouter) {}
  488. }
  489. /// Documentation for ServiceA
  490. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  491. public protocol NamespaceA_ServiceAServiceProtocol: NamespaceA_ServiceA.StreamingServiceProtocol {}
  492. /// Partial conformance to `NamespaceA_ServiceAStreamingServiceProtocol`.
  493. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  494. extension NamespaceA_ServiceA.ServiceProtocol {
  495. }
  496. /// Documentation for ServiceB
  497. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  498. public protocol NamespaceA_ServiceBStreamingServiceProtocol: GRPCCore.RegistrableRPCService {}
  499. /// Conformance to `GRPCCore.RegistrableRPCService`.
  500. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  501. extension NamespaceA_ServiceB.StreamingServiceProtocol {
  502. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  503. public func registerMethods(with router: inout GRPCCore.RPCRouter) {}
  504. }
  505. /// Documentation for ServiceB
  506. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  507. public protocol NamespaceA_ServiceBServiceProtocol: NamespaceA_ServiceB.StreamingServiceProtocol {}
  508. /// Partial conformance to `NamespaceA_ServiceBStreamingServiceProtocol`.
  509. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  510. extension NamespaceA_ServiceB.ServiceProtocol {
  511. }
  512. """
  513. try self.assertServerCodeTranslation(
  514. codeGenerationRequest: makeCodeGenerationRequest(services: [serviceA, serviceB]),
  515. expectedSwift: expectedSwift,
  516. accessLevel: .public
  517. )
  518. }
  519. private func assertServerCodeTranslation(
  520. codeGenerationRequest: CodeGenerationRequest,
  521. expectedSwift: String,
  522. accessLevel: SourceGenerator.Configuration.AccessLevel
  523. ) throws {
  524. let translator = ServerCodeTranslator(accessLevel: accessLevel)
  525. let codeBlocks = try translator.translate(from: codeGenerationRequest)
  526. let renderer = TextBasedRenderer.default
  527. renderer.renderCodeBlocks(codeBlocks)
  528. let contents = renderer.renderedContents()
  529. try XCTAssertEqualWithDiff(contents, expectedSwift)
  530. }
  531. }
  532. #endif // os(macOS) || os(Linux)