2
0

Utils.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. import Foundation
  17. import GRPC
  18. import SwiftProtobuf
  19. import XCTest
  20. internal func makeExtensions(
  21. forType typeName: String,
  22. number: Int
  23. ) -> [Google_Protobuf_FieldDescriptorProto] {
  24. var extensions: [Google_Protobuf_FieldDescriptorProto] = []
  25. for id in 1 ... number {
  26. extensions.append(
  27. Google_Protobuf_FieldDescriptorProto.with {
  28. $0.name = "extension" + typeName + "-" + String(id)
  29. $0.extendee = typeName
  30. $0.number = Int32(id)
  31. }
  32. )
  33. }
  34. return extensions
  35. }
  36. internal func generateFileDescriptorProto(
  37. fileName name: String,
  38. suffix: String
  39. ) -> Google_Protobuf_FileDescriptorProto {
  40. let inputMessage = Google_Protobuf_DescriptorProto.with {
  41. $0.name = "inputMessage" + suffix
  42. $0.field = [
  43. Google_Protobuf_FieldDescriptorProto.with {
  44. $0.name = "inputField"
  45. $0.type = .bool
  46. }
  47. ]
  48. }
  49. let packageName = "package" + name + suffix
  50. let inputMessageExtensions = makeExtensions(
  51. forType: "." + packageName + "." + "inputMessage" + suffix,
  52. number: 5
  53. )
  54. let outputMessage = Google_Protobuf_DescriptorProto.with {
  55. $0.name = "outputMessage" + suffix
  56. $0.field = [
  57. Google_Protobuf_FieldDescriptorProto.with {
  58. $0.name = "outputField"
  59. $0.type = .int32
  60. }
  61. ]
  62. }
  63. let enumType = Google_Protobuf_EnumDescriptorProto.with {
  64. $0.name = "enumType" + suffix
  65. $0.value = [
  66. Google_Protobuf_EnumValueDescriptorProto.with {
  67. $0.name = "value1"
  68. },
  69. Google_Protobuf_EnumValueDescriptorProto.with {
  70. $0.name = "value2"
  71. },
  72. ]
  73. }
  74. let method = Google_Protobuf_MethodDescriptorProto.with {
  75. $0.name = "testMethod" + suffix
  76. $0.inputType = inputMessage.name
  77. $0.outputType = outputMessage.name
  78. }
  79. let serviceDescriptor = Google_Protobuf_ServiceDescriptorProto.with {
  80. $0.method = [method]
  81. $0.name = "service" + suffix
  82. }
  83. let fileDescriptorProto = Google_Protobuf_FileDescriptorProto.with {
  84. $0.service = [serviceDescriptor]
  85. $0.name = name + suffix + ".proto"
  86. $0.package = "package" + name + suffix
  87. $0.messageType = [inputMessage, outputMessage]
  88. $0.enumType = [enumType]
  89. $0.extension = inputMessageExtensions
  90. }
  91. return fileDescriptorProto
  92. }
  93. /// Creates the dependencies of the proto used in the testing context.
  94. internal func makeProtosWithDependencies() -> [Google_Protobuf_FileDescriptorProto] {
  95. var fileDependencies: [Google_Protobuf_FileDescriptorProto] = []
  96. for id in 1 ... 4 {
  97. let fileDescriptorProto = generateFileDescriptorProto(fileName: "bar", suffix: String(id))
  98. if id != 1 {
  99. // Dependency of the first dependency.
  100. fileDependencies[0].dependency.append(fileDescriptorProto.name)
  101. }
  102. fileDependencies.append(fileDescriptorProto)
  103. }
  104. return fileDependencies
  105. }
  106. internal func makeProtosWithComplexDependencies() -> [Google_Protobuf_FileDescriptorProto] {
  107. var protos: [Google_Protobuf_FileDescriptorProto] = []
  108. protos.append(generateFileDescriptorProto(fileName: "foo", suffix: "0"))
  109. for id in 1 ... 10 {
  110. let fileDescriptorProtoA = generateFileDescriptorProto(
  111. fileName: "fooA",
  112. suffix: String(id) + "A"
  113. )
  114. let fileDescriptorProtoB = generateFileDescriptorProto(
  115. fileName: "fooB",
  116. suffix: String(id) + "B"
  117. )
  118. let parent = protos.count > 1 ? protos.count - Int.random(in: 1 ..< 3) : protos.count - 1
  119. protos[parent].dependency.append(fileDescriptorProtoA.name)
  120. protos[parent].dependency.append(fileDescriptorProtoB.name)
  121. protos.append(fileDescriptorProtoA)
  122. protos.append(fileDescriptorProtoB)
  123. }
  124. return protos
  125. }
  126. func XCTAssertThrowsGRPCStatus<T>(
  127. _ expression: @autoclosure () throws -> T,
  128. _ errorHandler: (GRPCStatus) -> Void
  129. ) {
  130. XCTAssertThrowsError(try expression()) { error in
  131. guard let error = error as? GRPCStatus else {
  132. return XCTFail("Error had unexpected type '\(type(of: error))'")
  133. }
  134. errorHandler(error)
  135. }
  136. }
  137. extension Sequence where Element == Google_Protobuf_FileDescriptorProto {
  138. var serviceNames: [String] {
  139. self.flatMap { $0.service.map { $0.name } }
  140. }
  141. }
  142. extension Sequence where Element == Google_Protobuf_EnumDescriptorProto {
  143. var names: [String] {
  144. self.map { $0.name }
  145. }
  146. }