StructuredSwift+MetadataTests.swift 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright 2024, 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. import Testing
  17. @testable import GRPCCodeGen
  18. extension StructuredSwiftTests {
  19. @Suite("Metadata")
  20. struct Metadata {
  21. @Test("typealias Input = <Name>", arguments: AccessModifier.allCases)
  22. func methodInputTypealias(access: AccessModifier) {
  23. let decl: TypealiasDescription = .methodInput(accessModifier: access, name: "Foo")
  24. let expected = "\(access) typealias Input = Foo"
  25. #expect(render(.typealias(decl)) == expected)
  26. }
  27. @Test("typealias Output = <Name>", arguments: AccessModifier.allCases)
  28. func methodOutputTypealias(access: AccessModifier) {
  29. let decl: TypealiasDescription = .methodOutput(accessModifier: access, name: "Foo")
  30. let expected = "\(access) typealias Output = Foo"
  31. #expect(render(.typealias(decl)) == expected)
  32. }
  33. @Test(
  34. "static let descriptor = GRPCCore.MethodDescriptor(...)",
  35. arguments: AccessModifier.allCases
  36. )
  37. func staticMethodDescriptorProperty(access: AccessModifier) {
  38. let decl: VariableDescription = .methodDescriptor(
  39. accessModifier: access,
  40. literalFullyQualifiedService: "foo.Foo",
  41. literalMethodName: "Bar"
  42. )
  43. let expected = """
  44. \(access) static let descriptor = GRPCCore.MethodDescriptor(
  45. service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "foo.Foo"),
  46. method: "Bar"
  47. )
  48. """
  49. #expect(render(.variable(decl)) == expected)
  50. }
  51. @Test(
  52. "static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService:)",
  53. arguments: AccessModifier.allCases
  54. )
  55. func staticServiceDescriptorProperty(access: AccessModifier) {
  56. let decl: VariableDescription = .serviceDescriptor(
  57. accessModifier: access,
  58. literalFullyQualifiedService: "foo.Bar"
  59. )
  60. let expected = """
  61. \(access) static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "foo.Bar")
  62. """
  63. #expect(render(.variable(decl)) == expected)
  64. }
  65. @Test("extension GRPCCore.ServiceDescriptor { ... }", arguments: AccessModifier.allCases)
  66. func staticServiceDescriptorPropertyExtension(access: AccessModifier) {
  67. let decl: ExtensionDescription = .serviceDescriptor(
  68. accessModifier: access,
  69. propertyName: "foo",
  70. literalFullyQualifiedService: "echo.EchoService"
  71. )
  72. let expected = """
  73. extension GRPCCore.ServiceDescriptor {
  74. /// Service descriptor for the "echo.EchoService" service.
  75. \(access) static let foo = GRPCCore.ServiceDescriptor(fullyQualifiedService: "echo.EchoService")
  76. }
  77. """
  78. #expect(render(.extension(decl)) == expected)
  79. }
  80. @Test(
  81. "static let descriptors: [GRPCCore.MethodDescriptor] = [...]",
  82. arguments: AccessModifier.allCases
  83. )
  84. func staticMethodDescriptorsArray(access: AccessModifier) {
  85. let decl: VariableDescription = .methodDescriptorsArray(
  86. accessModifier: access,
  87. methodNamespaceNames: ["Foo", "Bar", "Baz"]
  88. )
  89. let expected = """
  90. \(access) static let descriptors: [GRPCCore.MethodDescriptor] = [
  91. Foo.descriptor,
  92. Bar.descriptor,
  93. Baz.descriptor
  94. ]
  95. """
  96. #expect(render(.variable(decl)) == expected)
  97. }
  98. @Test("enum <Method> { ... }", arguments: AccessModifier.allCases)
  99. func methodNamespaceEnum(access: AccessModifier) {
  100. let decl: EnumDescription = .methodNamespace(
  101. accessModifier: access,
  102. name: "Foo",
  103. literalMethod: "Foo",
  104. literalFullyQualifiedService: "bar.Bar",
  105. inputType: "FooInput",
  106. outputType: "FooOutput"
  107. )
  108. let expected = """
  109. \(access) enum Foo {
  110. /// Request type for "Foo".
  111. \(access) typealias Input = FooInput
  112. /// Response type for "Foo".
  113. \(access) typealias Output = FooOutput
  114. /// Descriptor for "Foo".
  115. \(access) static let descriptor = GRPCCore.MethodDescriptor(
  116. service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "bar.Bar"),
  117. method: "Foo"
  118. )
  119. }
  120. """
  121. #expect(render(.enum(decl)) == expected)
  122. }
  123. @Test("enum Method { ... }", arguments: AccessModifier.allCases)
  124. func methodsNamespaceEnum(access: AccessModifier) {
  125. let decl: EnumDescription = .methodsNamespace(
  126. accessModifier: access,
  127. literalFullyQualifiedService: "bar.Bar",
  128. methods: [
  129. .init(
  130. documentation: "",
  131. name: .init(base: "Foo", generatedUpperCase: "Foo", generatedLowerCase: "foo"),
  132. isInputStreaming: false,
  133. isOutputStreaming: false,
  134. inputType: "FooInput",
  135. outputType: "FooOutput"
  136. )
  137. ]
  138. )
  139. let expected = """
  140. \(access) enum Method {
  141. /// Namespace for "Foo" metadata.
  142. \(access) enum Foo {
  143. /// Request type for "Foo".
  144. \(access) typealias Input = FooInput
  145. /// Response type for "Foo".
  146. \(access) typealias Output = FooOutput
  147. /// Descriptor for "Foo".
  148. \(access) static let descriptor = GRPCCore.MethodDescriptor(
  149. service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "bar.Bar"),
  150. method: "Foo"
  151. )
  152. }
  153. /// Descriptors for all methods in the "bar.Bar" service.
  154. \(access) static let descriptors: [GRPCCore.MethodDescriptor] = [
  155. Foo.descriptor
  156. ]
  157. }
  158. """
  159. #expect(render(.enum(decl)) == expected)
  160. }
  161. @Test("enum Method { ... } (no methods)", arguments: AccessModifier.allCases)
  162. func methodsNamespaceEnumNoMethods(access: AccessModifier) {
  163. let decl: EnumDescription = .methodsNamespace(
  164. accessModifier: access,
  165. literalFullyQualifiedService: "bar.Bar",
  166. methods: []
  167. )
  168. let expected = """
  169. \(access) enum Method {
  170. /// Descriptors for all methods in the "bar.Bar" service.
  171. \(access) static let descriptors: [GRPCCore.MethodDescriptor] = []
  172. }
  173. """
  174. #expect(render(.enum(decl)) == expected)
  175. }
  176. @Test("enum <Service> { ... }", arguments: AccessModifier.allCases)
  177. func serviceNamespaceEnum(access: AccessModifier) {
  178. let decl: EnumDescription = .serviceNamespace(
  179. accessModifier: access,
  180. name: "Foo",
  181. literalFullyQualifiedService: "Foo",
  182. methods: [
  183. .init(
  184. documentation: "",
  185. name: .init(base: "Bar", generatedUpperCase: "Bar", generatedLowerCase: "bar"),
  186. isInputStreaming: false,
  187. isOutputStreaming: false,
  188. inputType: "BarInput",
  189. outputType: "BarOutput"
  190. )
  191. ]
  192. )
  193. let expected = """
  194. \(access) enum Foo {
  195. /// Service descriptor for the "Foo" service.
  196. \(access) static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "Foo")
  197. /// Namespace for method metadata.
  198. \(access) enum Method {
  199. /// Namespace for "Bar" metadata.
  200. \(access) enum Bar {
  201. /// Request type for "Bar".
  202. \(access) typealias Input = BarInput
  203. /// Response type for "Bar".
  204. \(access) typealias Output = BarOutput
  205. /// Descriptor for "Bar".
  206. \(access) static let descriptor = GRPCCore.MethodDescriptor(
  207. service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "Foo"),
  208. method: "Bar"
  209. )
  210. }
  211. /// Descriptors for all methods in the "Foo" service.
  212. \(access) static let descriptors: [GRPCCore.MethodDescriptor] = [
  213. Bar.descriptor
  214. ]
  215. }
  216. }
  217. """
  218. #expect(render(.enum(decl)) == expected)
  219. }
  220. @Test("enum <Service> { ... } (no methods)", arguments: AccessModifier.allCases)
  221. func serviceNamespaceEnumNoMethods(access: AccessModifier) {
  222. let decl: EnumDescription = .serviceNamespace(
  223. accessModifier: access,
  224. name: "Foo",
  225. literalFullyQualifiedService: "Foo",
  226. methods: []
  227. )
  228. let expected = """
  229. \(access) enum Foo {
  230. /// Service descriptor for the "Foo" service.
  231. \(access) static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "Foo")
  232. /// Namespace for method metadata.
  233. \(access) enum Method {
  234. /// Descriptors for all methods in the "Foo" service.
  235. \(access) static let descriptors: [GRPCCore.MethodDescriptor] = []
  236. }
  237. }
  238. """
  239. #expect(render(.enum(decl)) == expected)
  240. }
  241. }
  242. }