PropertyWrapper.swift 9.7 KB

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