PropertyWrapperTests.swift 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright 2022 Google LLC
  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 FirebaseRemoteConfig
  17. import FirebaseRemoteConfigSwift
  18. import XCTest
  19. #if compiler(>=5.5.2) && canImport(_Concurrency)
  20. @available(iOS 14.0, macOS 11.0, macCatalyst 14.0, tvOS 14.0, watchOS 7.0, *)
  21. class PropertyWrapperTests: APITestBase {
  22. // MARK: - Test fetching Remote Config JSON values into struct property
  23. struct Recipe: Decodable {
  24. var recipeName: String
  25. var ingredients: [String]
  26. var cookTime: Int
  27. }
  28. static let fallbackString = "fallback"
  29. static let fallbackInt = 50
  30. static let fallbackFloat: Float = 50.2
  31. static let fallbackDouble: Double = 16_777_216.333921
  32. static let fallbackDecimal: Decimal = 235
  33. static let fallbackData = "hello".data(using: .utf8)!
  34. static let fallbackArray = ["mango", "pineapple", "papaya"]
  35. static let fallbackDict = [
  36. "session 0": "breakfast", "session 1": "keynote", "session 2": "state of union",
  37. ]
  38. static let fallbackJSON = Recipe(
  39. recipeName: "muffin", ingredients: ["flour", "sugar"], cookTime: 45
  40. )
  41. struct PropertyWrapperTester {
  42. @RemoteConfigProperty(key: Constants.stringKey, fallback: "")
  43. var stringValue: String!
  44. var stringKeyName: String {
  45. return _stringValue.key
  46. }
  47. @RemoteConfigProperty(key: Constants.intKey, fallback: 0)
  48. var intValue: Int!
  49. var intKeyName: String {
  50. return _intValue.key
  51. }
  52. @RemoteConfigProperty(key: Constants.floatKey, fallback: 0)
  53. var floatValue: Float!
  54. var floatKeyName: String {
  55. return _floatValue.key
  56. }
  57. @RemoteConfigProperty(key: Constants.floatKey, fallback: 0)
  58. var doubleValue: Double!
  59. var doubleKeyName: String {
  60. return _doubleValue.key
  61. }
  62. @RemoteConfigProperty(key: Constants.decimalKey, fallback: 0)
  63. var decimalValue: Decimal!
  64. var decimalKeyName: String {
  65. return _decimalValue.key
  66. }
  67. @RemoteConfigProperty(key: Constants.trueKey, fallback: false)
  68. var trueValue: Bool!
  69. var trueKeyName: String {
  70. return _trueValue.key
  71. }
  72. @RemoteConfigProperty(key: Constants.falseKey, fallback: false)
  73. var falseValue: Bool!
  74. var falseKeyName: String {
  75. return _falseValue.key
  76. }
  77. @RemoteConfigProperty(key: Constants.dataKey, fallback: Data())
  78. var dataValue: Data!
  79. var dataKeyName: String {
  80. return _dataValue.key
  81. }
  82. @RemoteConfigProperty(key: Constants.jsonKey, fallback: nil)
  83. var recipeValue: Recipe!
  84. var recipeKeyName: String {
  85. _recipeValue.key
  86. }
  87. @RemoteConfigProperty(key: Constants.arrayKey, fallback: [])
  88. var arrayValue: [String]!
  89. var arrayKeyName: String {
  90. _arrayValue.key
  91. }
  92. @RemoteConfigProperty(key: Constants.dictKey, fallback: [:])
  93. var dictValue: [String: String]!
  94. var dictKeyName: String {
  95. _dictValue.key
  96. }
  97. }
  98. struct PlaceholderValueTester {
  99. @RemoteConfigProperty(key: "NewKeyNotInSystem", fallback: fallbackString)
  100. var stringValue: String
  101. @RemoteConfigProperty(key: "NewIntKeyNotInSystem", fallback: fallbackInt)
  102. var intValue: Int!
  103. @RemoteConfigProperty(key: "NewZeroKey", fallback: 0)
  104. var zeroIntValue: Int!
  105. @RemoteConfigProperty(key: "newFloatKey", fallback: fallbackFloat)
  106. var floatValue: Float!
  107. @RemoteConfigProperty(key: "newDoubleKey", fallback: fallbackDouble)
  108. var doubleValue: Double!
  109. @RemoteConfigProperty(key: "newDecimalKey", fallback: fallbackDecimal)
  110. var decimalValue: Decimal!
  111. @RemoteConfigProperty(key: "newTrueKey", fallback: false)
  112. var trueKeyFalseValue: Bool!
  113. @RemoteConfigProperty(key: "newTrueKey2", fallback: true)
  114. var trueKeyTrueValue: Bool!
  115. @RemoteConfigProperty(key: "newFalseKey", fallback: true)
  116. var falseKeyTrueValue: Bool!
  117. @RemoteConfigProperty(key: "newFalseKey2", fallback: false)
  118. var falseKeyFalseValue: Bool!
  119. @RemoteConfigProperty(key: "newDataKey", fallback: fallbackData)
  120. var dataValue: Data
  121. @RemoteConfigProperty(key: "newJSONKey", fallback: fallbackJSON)
  122. var recipeValue: Recipe!
  123. @RemoteConfigProperty(key: "newArrayKey", fallback: fallbackArray)
  124. var arrayValue: [String]!
  125. @RemoteConfigProperty(key: "newDictKey", fallback: fallbackDict)
  126. var dictValue: [String: String]!
  127. }
  128. func testFetchAndActivateWithPropertyWrapper() async throws {
  129. let status = try await config.fetchAndActivate()
  130. XCTAssertEqual(status, .successFetchedFromRemote)
  131. let tester = await PropertyWrapperTester()
  132. let stringValue = await tester.stringValue
  133. XCTAssertEqual(stringValue, Constants.stringValue)
  134. let intValue = await tester.intValue
  135. XCTAssertEqual(intValue, Constants.intValue)
  136. let floatValue = await tester.floatValue
  137. XCTAssertEqual(floatValue, Constants.floatValue)
  138. let doubleValue = await tester.doubleValue
  139. XCTAssertEqual(doubleValue, Constants.doubleValue)
  140. let decimalValue = await tester.decimalValue
  141. XCTAssertEqual(decimalValue, Constants.decimalValue)
  142. let trueValue = await tester.trueValue
  143. XCTAssertEqual(trueValue, true)
  144. let falseValue = await tester.falseValue
  145. XCTAssertEqual(falseValue, false)
  146. let dataValue = await tester.dataValue
  147. XCTAssertEqual(dataValue, Constants.dataValue)
  148. let recipe = try XCTUnwrap(config[Constants.jsonKey].decoded(asType: Recipe.self))
  149. let recipeValue = await tester.recipeValue
  150. XCTAssertEqual(recipeValue?.recipeName, recipe.recipeName)
  151. XCTAssertEqual(recipeValue?.ingredients, recipe.ingredients)
  152. XCTAssertEqual(recipeValue?.cookTime, recipe.cookTime)
  153. let arrayValue = await tester.arrayValue
  154. XCTAssertEqual(arrayValue, Constants.arrayValue)
  155. let dictValue = await tester.dictValue
  156. XCTAssertEqual(dictValue, Constants.dictValue)
  157. }
  158. func testPropertyWrapperInstanceValues() async {
  159. let tester = await PropertyWrapperTester()
  160. let stringKeyName = await tester.stringKeyName
  161. XCTAssertEqual(Constants.stringKey, stringKeyName)
  162. let intKeyName = await tester.intKeyName
  163. XCTAssertEqual(Constants.intKey, intKeyName)
  164. let floatKeyName = await tester.floatKeyName
  165. XCTAssertEqual(Constants.floatKey, floatKeyName)
  166. let doubleKeyName = await tester.doubleKeyName
  167. XCTAssertEqual(Constants.floatKey, doubleKeyName)
  168. let decimalKeyName = await tester.decimalKeyName
  169. XCTAssertEqual(Constants.decimalKey, decimalKeyName)
  170. let trueKeyName = await tester.trueKeyName
  171. XCTAssertEqual(Constants.trueKey, trueKeyName)
  172. let falseKeyName = await tester.falseKeyName
  173. XCTAssertEqual(Constants.falseKey, falseKeyName)
  174. let dataKeyName = await tester.dataKeyName
  175. XCTAssertEqual(Constants.dataKey, dataKeyName)
  176. let recipeKeyName = await tester.recipeKeyName
  177. XCTAssertEqual(Constants.jsonKey, recipeKeyName)
  178. let arrayKeyName = await tester.arrayKeyName
  179. XCTAssertEqual(Constants.arrayKey, arrayKeyName)
  180. let dictKeyName = await tester.dictKeyName
  181. XCTAssertEqual(Constants.dictKey, dictKeyName)
  182. }
  183. func testPlaceHolderValues() async throws {
  184. // Make sure the values below are consistent with the property wrapper
  185. // in PlaceholderValueTester
  186. let tester = await PlaceholderValueTester()
  187. let stringValue = await tester.stringValue
  188. XCTAssertEqual(stringValue, PropertyWrapperTests.fallbackString)
  189. let intValue = await tester.intValue
  190. XCTAssertEqual(intValue, PropertyWrapperTests.fallbackInt)
  191. let zeroValue = await tester.zeroIntValue
  192. XCTAssertEqual(zeroValue, 0)
  193. let floatValue = await tester.floatValue
  194. XCTAssertEqual(floatValue, PropertyWrapperTests.fallbackFloat)
  195. let doubleValue = await tester.doubleValue
  196. XCTAssertEqual(doubleValue, PropertyWrapperTests.fallbackDouble)
  197. let decimalValue = await tester.decimalValue
  198. XCTAssertEqual(decimalValue, PropertyWrapperTests.fallbackDecimal)
  199. let trueKeyFalseValue = await tester.trueKeyFalseValue
  200. XCTAssertEqual(trueKeyFalseValue, false)
  201. let trueKeyTrueValue = await tester.trueKeyTrueValue
  202. XCTAssertEqual(trueKeyTrueValue, true)
  203. let falseKeyTrueValue = await tester.falseKeyTrueValue
  204. XCTAssertEqual(falseKeyTrueValue, true)
  205. let falseKeyFalseValue = await tester.falseKeyFalseValue
  206. XCTAssertEqual(falseKeyFalseValue, false)
  207. let dataValue = await tester.dataValue
  208. XCTAssertEqual(dataValue, PropertyWrapperTests.fallbackData)
  209. let arrayValue = await tester.arrayValue
  210. XCTAssertEqual(arrayValue, PropertyWrapperTests.fallbackArray)
  211. let dictValue = await tester.dictValue
  212. XCTAssertEqual(dictValue, PropertyWrapperTests.fallbackDict)
  213. let recipeValue = await tester.recipeValue
  214. XCTAssertEqual(recipeValue?.recipeName, "muffin")
  215. XCTAssertEqual(recipeValue?.ingredients, ["flour", "sugar"])
  216. XCTAssertEqual(recipeValue?.cookTime, 45)
  217. }
  218. }
  219. #endif