SerializerTests.swift 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. // Copyright 2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import Foundation
  15. import FirebaseCore
  16. @testable import FirebaseFunctions
  17. #if COCOAPODS
  18. import GTMSessionFetcher
  19. #else
  20. import GTMSessionFetcherCore
  21. #endif
  22. import XCTest
  23. class SerializerTests: XCTestCase {
  24. func testEncodeNull() throws {
  25. let serializer = FUNSerializer()
  26. let null = NSNull()
  27. XCTAssertEqual(try serializer.encode(null) as? NSNull, null)
  28. }
  29. func testDecodeNull() throws {
  30. let serializer = FUNSerializer()
  31. let null = NSNull()
  32. XCTAssertEqual(try serializer.decode(null) as? NSNull, null)
  33. }
  34. func testEncodeInt32() throws {
  35. let serializer = FUNSerializer()
  36. let one = NSNumber(value: 1 as Int32)
  37. XCTAssertEqual(one, try serializer.encode(one) as? NSNumber)
  38. }
  39. func testEncodeInt() throws {
  40. let serializer = FUNSerializer()
  41. let one = NSNumber(1)
  42. let dict = try XCTUnwrap(try serializer.encode(one) as? NSDictionary)
  43. XCTAssertEqual("type.googleapis.com/google.protobuf.Int64Value", dict["@type"] as? String)
  44. XCTAssertEqual("1", dict["value"] as? String)
  45. }
  46. func testDecodeInt32() throws {
  47. let serializer = FUNSerializer()
  48. let one = NSNumber(value: 1 as Int32)
  49. XCTAssertEqual(one, try serializer.decode(one) as? NSNumber)
  50. }
  51. func testDecodeInt() throws {
  52. let serializer = FUNSerializer()
  53. let one = NSNumber(1)
  54. XCTAssertEqual(one, try serializer.decode(one) as? NSNumber)
  55. }
  56. func testDecodeIntFromDictionary() throws {
  57. let serializer = FUNSerializer()
  58. let dictOne = ["@type": "type.googleapis.com/google.protobuf.Int64Value",
  59. "value": "1"]
  60. XCTAssertEqual(NSNumber(1), try serializer.decode(dictOne) as? NSNumber)
  61. }
  62. func testEncodeLong() throws {
  63. let serializer = FUNSerializer()
  64. let lowLong = NSNumber(-9_223_372_036_854_775_800)
  65. let dict = try XCTUnwrap(try serializer.encode(lowLong) as? NSDictionary)
  66. XCTAssertEqual("type.googleapis.com/google.protobuf.Int64Value", dict["@type"] as? String)
  67. XCTAssertEqual("-9223372036854775800", dict["value"] as? String)
  68. }
  69. func testDecodeLong() throws {
  70. let serializer = FUNSerializer()
  71. let lowLong = NSNumber(-9_223_372_036_854_775_800)
  72. XCTAssertEqual(lowLong, try serializer.decode(lowLong) as? NSNumber)
  73. }
  74. func testDecodeLongFromDictionary() throws {
  75. let serializer = FUNSerializer()
  76. let dictLowLong = ["@type": "type.googleapis.com/google.protobuf.Int64Value",
  77. "value": "-9223372036854775800"]
  78. let decoded = try serializer.decode(dictLowLong) as? NSNumber
  79. XCTAssertEqual(NSNumber(-9_223_372_036_854_775_800), decoded)
  80. // A naive implementation might convert a number to a double and think that's close enough.
  81. // We need to make sure it's a long long for accuracy.
  82. XCTAssertEqual(decoded?.objCType[0], CChar("q".utf8.first!))
  83. }
  84. func testDecodeInvalidLong() throws {
  85. let serializer = FUNSerializer()
  86. let typeString = "type.googleapis.com/google.protobuf.Int64Value"
  87. let badVal = "-9223372036854775800 and some other junk"
  88. let dictLowLong = ["@type": typeString, "value": badVal]
  89. do {
  90. _ = try serializer.decode(dictLowLong) as? NSNumber
  91. } catch let SerializerError.invalidValueForType(value, type) {
  92. XCTAssertEqual(value, badVal)
  93. XCTAssertEqual(type, typeString)
  94. return
  95. }
  96. XCTFail()
  97. }
  98. func testEncodeUnsignedLong() throws {
  99. let serializer = FUNSerializer()
  100. let typeString = "type.googleapis.com/google.protobuf.UInt64Value"
  101. let highULong = NSNumber(value: 18_446_744_073_709_551_607 as UInt64)
  102. let expected = ["@type": typeString, "value": "18446744073709551607"]
  103. let encoded = try serializer.encode(highULong) as? [String: String]
  104. XCTAssertEqual(encoded, expected)
  105. }
  106. func testDecodeUnsignedLong() throws {
  107. let serializer = FUNSerializer()
  108. let highULong = NSNumber(value: 18_446_744_073_709_551_607 as UInt64)
  109. XCTAssertEqual(highULong, try serializer.decode(highULong) as? NSNumber)
  110. }
  111. func testDecodeUnsignedLongFromDictionary() throws {
  112. let serializer = FUNSerializer()
  113. let typeString = "type.googleapis.com/google.protobuf.UInt64Value"
  114. let highULong = NSNumber(value: 18_446_744_073_709_551_607 as UInt64)
  115. let coded = ["@type": typeString, "value": "18446744073709551607"]
  116. let decoded = try serializer.decode(coded) as? NSNumber
  117. XCTAssertEqual(highULong, decoded)
  118. // A naive implementation might convert a number to a double and think that's close enough.
  119. // We need to make sure it's an unsigned long long for accuracy.
  120. XCTAssertEqual(decoded?.objCType[0], CChar("Q".utf8.first!))
  121. }
  122. func testDecodeUnsignedLongFromDictionaryOverflow() throws {
  123. let serializer = FUNSerializer()
  124. let typeString = "type.googleapis.com/google.protobuf.UInt64Value"
  125. let tooHighVal = "18446744073709551616"
  126. let coded = ["@type": typeString, "value": tooHighVal]
  127. do {
  128. _ = try serializer.decode(coded) as? NSNumber
  129. } catch let SerializerError.invalidValueForType(value, type) {
  130. XCTAssertEqual(value, tooHighVal)
  131. XCTAssertEqual(type, typeString)
  132. return
  133. }
  134. XCTFail()
  135. }
  136. func testEncodeDouble() throws {
  137. let serializer = FUNSerializer()
  138. let myDouble = NSNumber(value: 1.2 as Double)
  139. XCTAssertEqual(myDouble, try serializer.encode(myDouble) as? NSNumber)
  140. }
  141. func testDecodeDouble() throws {
  142. let serializer = FUNSerializer()
  143. let myDouble = NSNumber(value: 1.2 as Double)
  144. XCTAssertEqual(myDouble, try serializer.decode(myDouble) as? NSNumber)
  145. }
  146. func testEncodeBool() throws {
  147. let serializer = FUNSerializer()
  148. XCTAssertEqual(true, try serializer.encode(true) as? NSNumber)
  149. }
  150. func testDecodeBool() throws {
  151. let serializer = FUNSerializer()
  152. XCTAssertEqual(true, try serializer.decode(true) as? NSNumber)
  153. }
  154. func testEncodeString() throws {
  155. let serializer = FUNSerializer()
  156. XCTAssertEqual("hello", try serializer.encode("hello") as? String)
  157. }
  158. func testDecodeString() throws {
  159. let serializer = FUNSerializer()
  160. XCTAssertEqual("good-bye", try serializer.decode("good-bye") as? String)
  161. }
  162. // TODO: Should we add support for Array as well as NSArray?
  163. func testEncodeSimpleArray() throws {
  164. let serializer = FUNSerializer()
  165. let input = [1 as Int32, 2 as Int32] as NSArray
  166. XCTAssertEqual(input, try serializer.encode(input) as? NSArray)
  167. }
  168. func testEncodeArray() throws {
  169. let serializer = FUNSerializer()
  170. let input = [
  171. 1 as Int32,
  172. "two",
  173. [3 as Int32, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
  174. "value": "9876543210"]] as [Any],
  175. ] as NSArray
  176. XCTAssertEqual(input, try serializer.encode(input) as? NSArray)
  177. }
  178. func testDecodeArray() throws {
  179. let serializer = FUNSerializer()
  180. let input = [
  181. 1 as Int64,
  182. "two",
  183. [3 as Int32, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
  184. "value": "9876543210"]] as [Any],
  185. ] as NSArray
  186. let expected = [1 as Int64, "two", [3 as Int32, 9_876_543_210 as Int64] as [Any]] as NSArray
  187. XCTAssertEqual(expected, try serializer.decode(input) as? NSArray)
  188. }
  189. func testEncodeMap() {
  190. let input = [
  191. "foo": 1 as Int32,
  192. "bar": "hello",
  193. "baz": [3 as Int32, 9_876_543_210 as Int64] as [Any],
  194. ] as NSDictionary
  195. let expected = [
  196. "foo": 1,
  197. "bar": "hello",
  198. "baz": [3, ["@type": "type.googleapis.com/google.protobuf.Int64Value",
  199. "value": "9876543210"]] as [Any],
  200. ] as NSDictionary
  201. let serializer = FUNSerializer()
  202. XCTAssertEqual(expected, try serializer.encode(input) as? NSDictionary)
  203. }
  204. func testDecodeMap() {
  205. let input = ["foo": 1, "bar": "hello", "baz": [3, 9_876_543_210]] as NSDictionary
  206. let expected = ["foo": 1, "bar": "hello", "baz": [3, 9_876_543_210]] as NSDictionary
  207. let serializer = FUNSerializer()
  208. XCTAssertEqual(expected, try serializer.decode(input) as? NSDictionary)
  209. }
  210. func testEncodeUnknownType() {
  211. let input = ["@type": "unknown", "value": "whatever"] as NSDictionary
  212. let serializer = FUNSerializer()
  213. XCTAssertEqual(input, try serializer.encode(input) as? NSDictionary)
  214. }
  215. func testDecodeUnknownType() {
  216. let input = ["@type": "unknown", "value": "whatever"] as NSDictionary
  217. let serializer = FUNSerializer()
  218. XCTAssertEqual(input, try serializer.decode(input) as? NSDictionary)
  219. }
  220. func testDecodeUnknownTypeWithoutValue() {
  221. let input = ["@type": "unknown"] as NSDictionary
  222. let serializer = FUNSerializer()
  223. XCTAssertEqual(input, try serializer.decode(input) as? NSDictionary)
  224. }
  225. // - (void)testDecodeUnknownTypeWithoutValue {
  226. // NSDictionary *input = @{
  227. // @"@type" : @"unknown",
  228. // };
  229. // FUNSerializer *serializer = [[FUNSerializer alloc] init];
  230. // NSError *error = nil;
  231. // XCTAssertEqualObjects(input, [serializer decode:input error:&error]);
  232. // XCTAssertNil(error);
  233. // }
  234. //
  235. // @end
  236. }