StatusTests.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 GRPCCore
  17. import Testing
  18. @Suite("Status")
  19. struct StatusTests {
  20. @Suite("Code")
  21. struct Code {
  22. @Test("rawValue", arguments: zip(Status.Code.all, 0 ... 16))
  23. @available(gRPCSwift 2.0, *)
  24. func rawValueOfStatusCodes(code: Status.Code, expected: Int) {
  25. #expect(code.rawValue == expected)
  26. }
  27. @Test(
  28. "Initialize from RPCError.Code",
  29. arguments: zip(
  30. RPCError.Code.all,
  31. Status.Code.all.dropFirst() // Drop '.ok', there is no '.ok' error code.
  32. )
  33. )
  34. @available(gRPCSwift 2.0, *)
  35. func initFromRPCErrorCode(errorCode: RPCError.Code, expected: Status.Code) {
  36. #expect(Status.Code(errorCode) == expected)
  37. }
  38. @Test("Initialize from rawValue", arguments: zip(0 ... 16, Status.Code.all))
  39. @available(gRPCSwift 2.0, *)
  40. func initFromRawValue(rawValue: Int, expected: Status.Code) {
  41. #expect(Status.Code(rawValue: rawValue) == expected)
  42. }
  43. @Test("Initialize from invalid rawValue", arguments: [-1, 17, 100, .max])
  44. @available(gRPCSwift 2.0, *)
  45. func initFromInvalidRawValue(rawValue: Int) {
  46. #expect(Status.Code(rawValue: rawValue) == nil)
  47. }
  48. }
  49. @Test("CustomStringConvertible conformance")
  50. @available(gRPCSwift 2.0, *)
  51. func customStringConvertible() {
  52. #expect("\(Status(code: .ok, message: ""))" == #"ok: """#)
  53. #expect("\(Status(code: .dataLoss, message: "oh no"))" == #"dataLoss: "oh no""#)
  54. }
  55. @Test("Equatable conformance")
  56. @available(gRPCSwift 2.0, *)
  57. func equatable() {
  58. let ok = Status(code: .ok, message: "")
  59. let okWithMessage = Status(code: .ok, message: "message")
  60. let internalError = Status(code: .internalError, message: "")
  61. #expect(ok == ok)
  62. #expect(ok != okWithMessage)
  63. #expect(ok != internalError)
  64. }
  65. @Test("Fits in existential container")
  66. @available(gRPCSwift 2.0, *)
  67. func fitsInExistentialContainer() {
  68. #expect(MemoryLayout<Status>.size <= 24)
  69. }
  70. @Test(
  71. "From HTTP status code",
  72. arguments: [
  73. (400, Status(code: .internalError, message: "HTTP 400: Bad Request")),
  74. (401, Status(code: .unauthenticated, message: "HTTP 401: Unauthorized")),
  75. (403, Status(code: .permissionDenied, message: "HTTP 403: Forbidden")),
  76. (404, Status(code: .unimplemented, message: "HTTP 404: Not Found")),
  77. (429, Status(code: .unavailable, message: "HTTP 429: Too Many Requests")),
  78. (502, Status(code: .unavailable, message: "HTTP 502: Bad Gateway")),
  79. (503, Status(code: .unavailable, message: "HTTP 503: Service Unavailable")),
  80. (504, Status(code: .unavailable, message: "HTTP 504: Gateway Timeout")),
  81. (418, Status(code: .unknown, message: "HTTP 418")),
  82. ]
  83. )
  84. @available(gRPCSwift 2.0, *)
  85. func convertFromHTTPStatusCode(code: Int, expected: Status) {
  86. let status = Status(httpStatusCode: code)
  87. #expect(status == expected)
  88. }
  89. }