ObjectCreationTests.swift 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2015 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import XCTest
  19. import RealmSwift
  20. import Realm.Private
  21. class ObjectWithPrivateOptionals: Object {
  22. private var nilInt: Int?
  23. private var nilFloat: Float?
  24. private var nilString: String?
  25. private var int: Int? = 123
  26. private var float: Float? = 1.23
  27. private var string: String? = "123"
  28. @objc dynamic var value = 5
  29. }
  30. class ObjectCreationTests: TestCase {
  31. // MARK: Init tests
  32. func testInitWithDefaults() {
  33. // test all properties are defaults
  34. let object = SwiftObject()
  35. XCTAssertNil(object.realm)
  36. // test defaults values
  37. verifySwiftObjectWithDictionaryLiteral(object, dictionary: SwiftObject.defaultValues(), boolObjectValue: false,
  38. boolObjectListValues: [])
  39. // test realm properties are nil for standalone
  40. XCTAssertNil(object.realm)
  41. XCTAssertNil(object.objectCol!.realm)
  42. XCTAssertNil(object.arrayCol.realm)
  43. }
  44. func testInitWithOptionalWithoutDefaults() {
  45. let object = SwiftOptionalObject()
  46. for prop in object.objectSchema.properties {
  47. let value = object[prop.name]
  48. if let value = value as? RLMOptionalBase {
  49. XCTAssertNil(RLMGetOptional(value))
  50. } else {
  51. XCTAssertNil(value)
  52. }
  53. }
  54. }
  55. func testInitWithOptionalDefaults() {
  56. let object = SwiftOptionalDefaultValuesObject()
  57. verifySwiftOptionalObjectWithDictionaryLiteral(object, dictionary:
  58. SwiftOptionalDefaultValuesObject.defaultValues(), boolObjectValue: true)
  59. }
  60. func testInitWithDictionary() {
  61. // dictionary with all values specified
  62. let baselineValues: [String: Any] =
  63. ["boolCol": true,
  64. "intCol": 1,
  65. "floatCol": 1.1 as Float,
  66. "doubleCol": 11.1,
  67. "stringCol": "b",
  68. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  69. "dateCol": Date(timeIntervalSince1970: 2),
  70. "objectCol": SwiftBoolObject(value: [true]),
  71. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  72. ]
  73. // test with valid dictionary literals
  74. let props = try! Realm().schema["SwiftObject"]!.properties
  75. for propNum in 0..<props.count {
  76. for validValue in validValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  77. // update dict with valid value and init
  78. var values = baselineValues
  79. values[props[propNum].name] = validValue
  80. let object = SwiftObject(value: values)
  81. verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true,
  82. boolObjectListValues: [true, false])
  83. }
  84. }
  85. // test with invalid dictionary literals
  86. for propNum in 0..<props.count {
  87. for invalidValue in invalidValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  88. // update dict with invalid value and init
  89. var values = baselineValues
  90. values[props[propNum].name] = invalidValue
  91. assertThrows(SwiftObject(value: values), "Invalid property value")
  92. }
  93. }
  94. }
  95. func testInitWithDefaultsAndDictionary() {
  96. // test with dictionary with mix of default and one specified value
  97. let object = SwiftObject(value: ["intCol": 200])
  98. let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200])
  99. verifySwiftObjectWithDictionaryLiteral(object, dictionary: valueDict, boolObjectValue: false,
  100. boolObjectListValues: [])
  101. }
  102. func testInitWithArray() {
  103. // array with all values specified
  104. let baselineValues: [Any] = [true, 1, IntEnum.value1.rawValue, 1.1 as Float,
  105. 11.1, "b", "b".data(using: String.Encoding.utf8)!,
  106. Date(timeIntervalSince1970: 2), ["boolCol": true],
  107. [[true], [false]]]
  108. // test with valid dictionary literals
  109. let props = try! Realm().schema["SwiftObject"]!.properties
  110. for propNum in 0..<props.count {
  111. for validValue in validValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  112. // update dict with valid value and init
  113. var values = baselineValues
  114. values[propNum] = validValue
  115. let object = SwiftObject(value: values)
  116. verifySwiftObjectWithArrayLiteral(object, array: values, boolObjectValue: true,
  117. boolObjectListValues: [true, false])
  118. }
  119. }
  120. // test with invalid dictionary literals
  121. for propNum in 0..<props.count {
  122. for invalidValue in invalidValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  123. // update dict with invalid value and init
  124. var values = baselineValues
  125. values[propNum] = invalidValue
  126. assertThrows(SwiftObject(value: values), "Invalid property value")
  127. }
  128. }
  129. }
  130. func testInitWithKVCObject() {
  131. // test with kvc object
  132. let objectWithInt = SwiftObject(value: ["intCol": 200])
  133. let objectWithKVCObject = SwiftObject(value: objectWithInt)
  134. let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200])
  135. verifySwiftObjectWithDictionaryLiteral(objectWithKVCObject, dictionary: valueDict, boolObjectValue: false,
  136. boolObjectListValues: [])
  137. }
  138. func testGenericInit() {
  139. func createObject<T: Object>() -> T {
  140. return T()
  141. }
  142. let obj1: SwiftBoolObject = createObject()
  143. let obj2 = SwiftBoolObject()
  144. XCTAssertEqual(obj1.boolCol, obj2.boolCol,
  145. "object created via generic initializer should equal object created by calling initializer directly")
  146. }
  147. func testInitWithObjcName() {
  148. // Test that init doesn't crash going into non-swift init logic for renamed Swift classes.
  149. _ = SwiftObjcRenamedObject()
  150. _ = SwiftObjcArbitrarilyRenamedObject()
  151. }
  152. // MARK: Creation tests
  153. func testCreateWithDefaults() {
  154. let realm = try! Realm()
  155. assertThrows(realm.create(SwiftObject.self), "Must be in write transaction")
  156. var object: SwiftObject!
  157. let objects = realm.objects(SwiftObject.self)
  158. XCTAssertEqual(0, objects.count)
  159. try! realm.write {
  160. // test create with all defaults
  161. object = realm.create(SwiftObject.self)
  162. return
  163. }
  164. verifySwiftObjectWithDictionaryLiteral(object, dictionary: SwiftObject.defaultValues(), boolObjectValue: false,
  165. boolObjectListValues: [])
  166. // test realm properties are populated correctly
  167. XCTAssertEqual(object.realm!, realm)
  168. XCTAssertEqual(object.objectCol!.realm!, realm)
  169. XCTAssertEqual(object.arrayCol.realm!, realm)
  170. }
  171. func testCreateWithOptionalWithoutDefaults() {
  172. let realm = try! Realm()
  173. try! realm.write {
  174. let object = realm.create(SwiftOptionalObject.self)
  175. for prop in object.objectSchema.properties {
  176. XCTAssertNil(object[prop.name])
  177. }
  178. }
  179. }
  180. func testCreateWithOptionalDefaults() {
  181. let realm = try! Realm()
  182. try! realm.write {
  183. let object = realm.create(SwiftOptionalDefaultValuesObject.self)
  184. self.verifySwiftOptionalObjectWithDictionaryLiteral(object,
  185. dictionary: SwiftOptionalDefaultValuesObject.defaultValues(), boolObjectValue: true)
  186. }
  187. }
  188. func testCreateWithOptionalIgnoredProperties() {
  189. let realm = try! Realm()
  190. try! realm.write {
  191. let object = realm.create(SwiftOptionalIgnoredPropertiesObject.self)
  192. let properties = object.objectSchema.properties
  193. XCTAssertEqual(properties.count, 1)
  194. XCTAssertEqual(properties[0].name, "id")
  195. }
  196. }
  197. func testCreateWithDictionary() {
  198. // dictionary with all values specified
  199. let baselineValues: [String: Any] = [
  200. "boolCol": true,
  201. "intCol": 1,
  202. "floatCol": 1.1 as Float,
  203. "doubleCol": 11.1,
  204. "stringCol": "b",
  205. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  206. "dateCol": Date(timeIntervalSince1970: 2),
  207. "objectCol": SwiftBoolObject(value: [true]),
  208. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  209. ]
  210. // test with valid dictionary literals
  211. let props = try! Realm().schema["SwiftObject"]!.properties
  212. for propNum in 0..<props.count {
  213. for validValue in validValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  214. // update dict with valid value and init
  215. var values = baselineValues
  216. values[props[propNum].name] = validValue
  217. try! Realm().beginWrite()
  218. let object = try! Realm().create(SwiftObject.self, value: values)
  219. verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true,
  220. boolObjectListValues: [true, false])
  221. try! Realm().commitWrite()
  222. verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true,
  223. boolObjectListValues: [true, false])
  224. }
  225. }
  226. // test with invalid dictionary literals
  227. for propNum in 0..<props.count {
  228. for invalidValue in invalidValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  229. // update dict with invalid value and init
  230. var values = baselineValues
  231. values[props[propNum].name] = invalidValue
  232. try! Realm().beginWrite()
  233. assertThrows(try! Realm().create(SwiftObject.self, value: values), "Invalid property value")
  234. try! Realm().cancelWrite()
  235. }
  236. }
  237. }
  238. func testCreateWithDefaultsAndDictionary() {
  239. // test with dictionary with mix of default and one specified value
  240. let realm = try! Realm()
  241. realm.beginWrite()
  242. let objectWithInt = realm.create(SwiftObject.self, value: ["intCol": 200])
  243. try! realm.commitWrite()
  244. let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200])
  245. verifySwiftObjectWithDictionaryLiteral(objectWithInt, dictionary: valueDict, boolObjectValue: false,
  246. boolObjectListValues: [])
  247. }
  248. func testCreateWithArray() {
  249. // array with all values specified
  250. let baselineValues: [Any] = [true, 1, IntEnum.value1.rawValue, 1.1 as Float, 11.1, "b", "b".data(using: String.Encoding.utf8)!,
  251. Date(timeIntervalSince1970: 2), ["boolCol": true], [[true], [false]]]
  252. // test with valid dictionary literals
  253. let props = try! Realm().schema["SwiftObject"]!.properties
  254. for propNum in 0..<props.count {
  255. for validValue in validValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  256. // update dict with valid value and init
  257. var values = baselineValues
  258. values[propNum] = validValue
  259. try! Realm().beginWrite()
  260. let object = try! Realm().create(SwiftObject.self, value: values)
  261. verifySwiftObjectWithArrayLiteral(object, array: values, boolObjectValue: true,
  262. boolObjectListValues: [true, false])
  263. try! Realm().commitWrite()
  264. verifySwiftObjectWithArrayLiteral(object, array: values, boolObjectValue: true,
  265. boolObjectListValues: [true, false])
  266. }
  267. }
  268. // test with invalid array literals
  269. for propNum in 0..<props.count {
  270. for invalidValue in invalidValuesForSwiftObjectType(props[propNum].type, props[propNum].isArray) {
  271. // update dict with invalid value and init
  272. var values = baselineValues
  273. values[propNum] = invalidValue
  274. try! Realm().beginWrite()
  275. assertThrows(try! Realm().create(SwiftObject.self, value: values),
  276. "Invalid property value '\(invalidValue)' for property number \(propNum)")
  277. try! Realm().cancelWrite()
  278. }
  279. }
  280. }
  281. func testCreateWithKVCObject() {
  282. // test with kvc object
  283. try! Realm().beginWrite()
  284. let objectWithInt = try! Realm().create(SwiftObject.self, value: ["intCol": 200])
  285. let objectWithKVCObject = try! Realm().create(SwiftObject.self, value: objectWithInt)
  286. let valueDict = defaultSwiftObjectValuesWithReplacements(["intCol": 200])
  287. try! Realm().commitWrite()
  288. verifySwiftObjectWithDictionaryLiteral(objectWithKVCObject, dictionary: valueDict, boolObjectValue: false,
  289. boolObjectListValues: [])
  290. XCTAssertEqual(try! Realm().objects(SwiftObject.self).count, 2, "Object should have been copied")
  291. }
  292. func testCreateWithNestedObjects() {
  293. let standalone = SwiftPrimaryStringObject(value: ["p0", 11])
  294. try! Realm().beginWrite()
  295. let objectWithNestedObjects = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["p1", ["p1", 11],
  296. [standalone]])
  297. try! Realm().commitWrite()
  298. let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
  299. XCTAssertEqual(stringObjects.count, 2)
  300. let persistedObject = stringObjects.first!
  301. // standalone object should be copied into the realm, not added directly
  302. XCTAssertNotEqual(standalone, persistedObject)
  303. XCTAssertEqual(objectWithNestedObjects.object!, persistedObject)
  304. XCTAssertEqual(objectWithNestedObjects.objects.first!, stringObjects.last!)
  305. let standalone1 = SwiftPrimaryStringObject(value: ["p3", 11])
  306. try! Realm().beginWrite()
  307. assertThrows(try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["p3", ["p3", 11], [standalone1]]),
  308. "Should throw with duplicate primary key")
  309. try! Realm().commitWrite()
  310. }
  311. func testUpdateWithNestedObjects() {
  312. let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
  313. try! Realm().beginWrite()
  314. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
  315. [["primary", 12]]], update: .all)
  316. try! Realm().commitWrite()
  317. let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
  318. XCTAssertEqual(stringObjects.count, 1)
  319. let persistedObject = object.object!
  320. XCTAssertEqual(persistedObject.intCol, 12)
  321. XCTAssertNil(standalone.realm) // the standalone object should be copied, rather than added, to the realm
  322. XCTAssertEqual(object.object!, persistedObject)
  323. XCTAssertEqual(object.objects.first!, persistedObject)
  324. }
  325. func testUpdateChangedWithNestedObjects() {
  326. let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
  327. try! Realm().beginWrite()
  328. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
  329. [["primary", 12]]], update: .modified)
  330. try! Realm().commitWrite()
  331. let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
  332. XCTAssertEqual(stringObjects.count, 1)
  333. let persistedObject = object.object!
  334. XCTAssertEqual(persistedObject.intCol, 12)
  335. XCTAssertNil(standalone.realm) // the standalone object should be copied, rather than added, to the realm
  336. XCTAssertEqual(object.object!, persistedObject)
  337. XCTAssertEqual(object.objects.first!, persistedObject)
  338. }
  339. func testCreateWithObjectsFromAnotherRealm() {
  340. let values: [String: Any] = [
  341. "boolCol": true,
  342. "intCol": 1,
  343. "floatCol": 1.1 as Float,
  344. "doubleCol": 11.1,
  345. "stringCol": "b",
  346. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  347. "dateCol": Date(timeIntervalSince1970: 2),
  348. "objectCol": SwiftBoolObject(value: [true]),
  349. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  350. ]
  351. realmWithTestPath().beginWrite()
  352. let otherRealmObject = realmWithTestPath().create(SwiftObject.self, value: values)
  353. try! realmWithTestPath().commitWrite()
  354. try! Realm().beginWrite()
  355. let object = try! Realm().create(SwiftObject.self, value: otherRealmObject)
  356. try! Realm().commitWrite()
  357. XCTAssertNotEqual(otherRealmObject, object)
  358. verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true,
  359. boolObjectListValues: [true, false])
  360. }
  361. func testCreateWithDeeplyNestedObjectsFromAnotherRealm() {
  362. let values: [String: Any] = [
  363. "boolCol": true,
  364. "intCol": 1,
  365. "floatCol": 1.1 as Float,
  366. "doubleCol": 11.1,
  367. "stringCol": "b",
  368. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  369. "dateCol": Date(timeIntervalSince1970: 2),
  370. "objectCol": SwiftBoolObject(value: [true]),
  371. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  372. ]
  373. let realmA = realmWithTestPath()
  374. let realmB = try! Realm()
  375. var realmAObject: SwiftListOfSwiftObject?
  376. try! realmA.write {
  377. let array = [SwiftObject(value: values), SwiftObject(value: values)]
  378. realmAObject = realmA.create(SwiftListOfSwiftObject.self, value: ["array": array])
  379. }
  380. var realmBObject: SwiftListOfSwiftObject!
  381. try! realmB.write {
  382. realmBObject = realmB.create(SwiftListOfSwiftObject.self, value: realmAObject!)
  383. }
  384. XCTAssertNotEqual(realmAObject, realmBObject)
  385. XCTAssertEqual(realmBObject.array.count, 2)
  386. for swiftObject in realmBObject.array {
  387. verifySwiftObjectWithDictionaryLiteral(swiftObject, dictionary: values, boolObjectValue: true,
  388. boolObjectListValues: [true, false])
  389. }
  390. }
  391. func testUpdateWithObjectsFromAnotherRealm() {
  392. realmWithTestPath().beginWrite()
  393. let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self,
  394. value: ["primary", NSNull(), [["2", 2], ["4", 4]]])
  395. try! realmWithTestPath().commitWrite()
  396. try! Realm().beginWrite()
  397. try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
  398. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .all)
  399. try! Realm().commitWrite()
  400. XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
  401. XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1)
  402. XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4)
  403. }
  404. func testUpdateChangedWithObjectsFromAnotherRealm() {
  405. realmWithTestPath().beginWrite()
  406. let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self,
  407. value: ["primary", NSNull(), [["2", 2], ["4", 4]]])
  408. try! realmWithTestPath().commitWrite()
  409. try! Realm().beginWrite()
  410. try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
  411. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .modified)
  412. try! Realm().commitWrite()
  413. XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
  414. XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1)
  415. XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4)
  416. }
  417. func testCreateWithNSNullLinks() {
  418. let values: [String: Any] = [
  419. "boolCol": true,
  420. "intCol": 1,
  421. "floatCol": 1.1,
  422. "doubleCol": 11.1,
  423. "stringCol": "b",
  424. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  425. "dateCol": Date(timeIntervalSince1970: 2),
  426. "objectCol": NSNull(),
  427. "arrayCol": NSNull()
  428. ]
  429. realmWithTestPath().beginWrite()
  430. let object = realmWithTestPath().create(SwiftObject.self, value: values)
  431. try! realmWithTestPath().commitWrite()
  432. XCTAssert(object.objectCol == nil) // XCTAssertNil caused a NULL deref inside _swift_getClass
  433. XCTAssertEqual(object.arrayCol.count, 0)
  434. }
  435. func testCreateWithObjcName() {
  436. let realm = try! Realm()
  437. try! realm.write {
  438. let object = realm.create(SwiftObjcRenamedObject.self)
  439. object.stringCol = "string"
  440. }
  441. XCTAssertEqual(realm.objects(SwiftObjcRenamedObject.self).count, 1)
  442. try! realm.write {
  443. realm.delete(realm.objects(SwiftObjcRenamedObject.self))
  444. }
  445. }
  446. func testCreateWithDifferentObjcName() {
  447. let realm = try! Realm()
  448. try! realm.write {
  449. let object = realm.create(SwiftObjcArbitrarilyRenamedObject.self)
  450. object.boolCol = true
  451. }
  452. XCTAssertEqual(realm.objects(SwiftObjcArbitrarilyRenamedObject.self).count, 1)
  453. try! realm.write {
  454. realm.delete(realm.objects(SwiftObjcArbitrarilyRenamedObject.self))
  455. }
  456. }
  457. func testCreateOrUpdateNil() {
  458. let realm = try! Realm()
  459. realm.beginWrite()
  460. // Create with all fields nil
  461. let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
  462. XCTAssertNil(object.id.value)
  463. XCTAssertNil(object.optIntCol.value)
  464. XCTAssertNil(object.optInt8Col.value)
  465. XCTAssertNil(object.optInt16Col.value)
  466. XCTAssertNil(object.optInt32Col.value)
  467. XCTAssertNil(object.optInt64Col.value)
  468. XCTAssertNil(object.optBoolCol.value)
  469. XCTAssertNil(object.optFloatCol.value)
  470. XCTAssertNil(object.optDoubleCol.value)
  471. XCTAssertNil(object.optDateCol)
  472. XCTAssertNil(object.optStringCol)
  473. XCTAssertNil(object.optNSStringCol)
  474. XCTAssertNil(object.optBinaryCol)
  475. XCTAssertNil(object.optObjectCol)
  476. // Try to switch to non-nil
  477. let object2 = SwiftOptionalPrimaryObject()
  478. object2.optIntCol.value = 1
  479. object2.optInt8Col.value = 1
  480. object2.optInt16Col.value = 1
  481. object2.optInt32Col.value = 1
  482. object2.optInt64Col.value = 1
  483. object2.optFloatCol.value = 1
  484. object2.optDoubleCol.value = 1
  485. object2.optBoolCol.value = true
  486. object2.optDateCol = Date()
  487. object2.optStringCol = ""
  488. object2.optNSStringCol = ""
  489. object2.optBinaryCol = Data()
  490. object2.optObjectCol = SwiftBoolObject()
  491. realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .all)
  492. XCTAssertNil(object.id.value)
  493. XCTAssertNotNil(object.optIntCol.value)
  494. XCTAssertNotNil(object.optInt8Col.value)
  495. XCTAssertNotNil(object.optInt16Col.value)
  496. XCTAssertNotNil(object.optInt32Col.value)
  497. XCTAssertNotNil(object.optInt64Col.value)
  498. XCTAssertNotNil(object.optBoolCol.value)
  499. XCTAssertNotNil(object.optFloatCol.value)
  500. XCTAssertNotNil(object.optDoubleCol.value)
  501. XCTAssertNotNil(object.optDateCol)
  502. XCTAssertNotNil(object.optStringCol)
  503. XCTAssertNotNil(object.optNSStringCol)
  504. XCTAssertNotNil(object.optBinaryCol)
  505. XCTAssertNotNil(object.optObjectCol)
  506. // Try to switch back to nil
  507. realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
  508. XCTAssertNil(object.id.value)
  509. XCTAssertNil(object.optIntCol.value)
  510. XCTAssertNil(object.optInt8Col.value)
  511. XCTAssertNil(object.optInt16Col.value)
  512. XCTAssertNil(object.optInt32Col.value)
  513. XCTAssertNil(object.optInt64Col.value)
  514. XCTAssertNil(object.optBoolCol.value)
  515. XCTAssertNil(object.optFloatCol.value)
  516. XCTAssertNil(object.optDoubleCol.value)
  517. XCTAssertNil(object.optDateCol)
  518. XCTAssertNil(object.optStringCol)
  519. XCTAssertNil(object.optNSStringCol)
  520. XCTAssertNil(object.optBinaryCol)
  521. XCTAssertNil(object.optObjectCol)
  522. realm.cancelWrite()
  523. }
  524. func testCreateOrUpdateModifiedNil() {
  525. let realm = try! Realm()
  526. realm.beginWrite()
  527. // Create with all fields nil
  528. let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
  529. XCTAssertNil(object.id.value)
  530. XCTAssertNil(object.optIntCol.value)
  531. XCTAssertNil(object.optInt8Col.value)
  532. XCTAssertNil(object.optInt16Col.value)
  533. XCTAssertNil(object.optInt32Col.value)
  534. XCTAssertNil(object.optInt64Col.value)
  535. XCTAssertNil(object.optBoolCol.value)
  536. XCTAssertNil(object.optFloatCol.value)
  537. XCTAssertNil(object.optDoubleCol.value)
  538. XCTAssertNil(object.optDateCol)
  539. XCTAssertNil(object.optStringCol)
  540. XCTAssertNil(object.optNSStringCol)
  541. XCTAssertNil(object.optBinaryCol)
  542. XCTAssertNil(object.optObjectCol)
  543. // Try to switch to non-nil
  544. let object2 = SwiftOptionalPrimaryObject()
  545. object2.optIntCol.value = 1
  546. object2.optInt8Col.value = 1
  547. object2.optInt16Col.value = 1
  548. object2.optInt32Col.value = 1
  549. object2.optInt64Col.value = 1
  550. object2.optFloatCol.value = 1
  551. object2.optDoubleCol.value = 1
  552. object2.optBoolCol.value = true
  553. object2.optDateCol = Date()
  554. object2.optStringCol = ""
  555. object2.optNSStringCol = ""
  556. object2.optBinaryCol = Data()
  557. object2.optObjectCol = SwiftBoolObject()
  558. realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .modified)
  559. XCTAssertNil(object.id.value)
  560. XCTAssertNotNil(object.optIntCol.value)
  561. XCTAssertNotNil(object.optInt8Col.value)
  562. XCTAssertNotNil(object.optInt16Col.value)
  563. XCTAssertNotNil(object.optInt32Col.value)
  564. XCTAssertNotNil(object.optInt64Col.value)
  565. XCTAssertNotNil(object.optBoolCol.value)
  566. XCTAssertNotNil(object.optFloatCol.value)
  567. XCTAssertNotNil(object.optDoubleCol.value)
  568. XCTAssertNotNil(object.optDateCol)
  569. XCTAssertNotNil(object.optStringCol)
  570. XCTAssertNotNil(object.optNSStringCol)
  571. XCTAssertNotNil(object.optBinaryCol)
  572. XCTAssertNotNil(object.optObjectCol)
  573. // Try to switch back to nil
  574. realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
  575. XCTAssertNil(object.id.value)
  576. XCTAssertNil(object.optIntCol.value)
  577. XCTAssertNil(object.optInt8Col.value)
  578. XCTAssertNil(object.optInt16Col.value)
  579. XCTAssertNil(object.optInt32Col.value)
  580. XCTAssertNil(object.optInt64Col.value)
  581. XCTAssertNil(object.optBoolCol.value)
  582. XCTAssertNil(object.optFloatCol.value)
  583. XCTAssertNil(object.optDoubleCol.value)
  584. XCTAssertNil(object.optDateCol)
  585. XCTAssertNil(object.optStringCol)
  586. XCTAssertNil(object.optNSStringCol)
  587. XCTAssertNil(object.optBinaryCol)
  588. XCTAssertNil(object.optObjectCol)
  589. realm.cancelWrite()
  590. }
  591. func testCreateOrUpdateDynamicUnmanagedType() {
  592. let realm = try! Realm()
  593. let unmanagedValue = SwiftOptionalPrimaryObject()
  594. // Shouldn't throw.
  595. realm.beginWrite()
  596. _ = realm.create(type(of: unmanagedValue), value: unmanagedValue, update: .modified)
  597. realm.cancelWrite()
  598. }
  599. func testCreateOrUpdateDynamicManagedType() {
  600. let realm = try! Realm()
  601. let managedValue = SwiftOptionalPrimaryObject()
  602. try! realm.write {
  603. realm.add(managedValue)
  604. }
  605. // Shouldn't throw.
  606. realm.beginWrite()
  607. _ = realm.create(type(of: managedValue), value: managedValue, update: .all)
  608. realm.cancelWrite()
  609. }
  610. func testCreateOrUpdateModifiedDynamicManagedType() {
  611. let realm = try! Realm()
  612. let managedValue = SwiftOptionalPrimaryObject()
  613. try! realm.write {
  614. realm.add(managedValue)
  615. }
  616. // Shouldn't throw.
  617. realm.beginWrite()
  618. _ = realm.create(type(of: managedValue), value: managedValue, update: .modified)
  619. realm.cancelWrite()
  620. }
  621. func testCreateOrUpdateWithMismatchedStaticAndDynamicTypes() {
  622. let realm = try! Realm()
  623. let obj: Object = SwiftOptionalPrimaryObject()
  624. try! realm.write {
  625. let obj2 = realm.create(type(of: obj), value: obj)
  626. XCTAssertEqual(obj2.objectSchema.className, "SwiftOptionalPrimaryObject")
  627. let obj3 = realm.create(type(of: obj), value: obj, update: .all)
  628. XCTAssertEqual(obj3.objectSchema.className, "SwiftOptionalPrimaryObject")
  629. }
  630. }
  631. // test null object
  632. // test null list
  633. // MARK: Add tests
  634. func testAddWithExisingNestedObjects() {
  635. try! Realm().beginWrite()
  636. let existingObject = try! Realm().create(SwiftBoolObject.self)
  637. try! Realm().commitWrite()
  638. try! Realm().beginWrite()
  639. let object = SwiftObject(value: ["objectCol": existingObject])
  640. try! Realm().add(object)
  641. try! Realm().commitWrite()
  642. XCTAssertNotNil(object.realm)
  643. assertEqual(object.objectCol, existingObject)
  644. }
  645. func testAddAndUpdateWithExisingNestedObjects() {
  646. try! Realm().beginWrite()
  647. let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1])
  648. try! Realm().commitWrite()
  649. try! Realm().beginWrite()
  650. let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
  651. try! Realm().add(object, update: .all)
  652. try! Realm().commitWrite()
  653. XCTAssertNotNil(object.realm)
  654. XCTAssertEqual(object.object!, existingObject) // the existing object should be updated
  655. XCTAssertEqual(existingObject.intCol, 2)
  656. }
  657. func testAddAndUpdateChangedWithExisingNestedObjects() {
  658. try! Realm().beginWrite()
  659. let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1])
  660. try! Realm().commitWrite()
  661. try! Realm().beginWrite()
  662. let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
  663. try! Realm().add(object, update: .modified)
  664. try! Realm().commitWrite()
  665. XCTAssertNotNil(object.realm)
  666. XCTAssertEqual(object.object!, existingObject) // the existing object should be updated
  667. XCTAssertEqual(existingObject.intCol, 2)
  668. }
  669. func testAddObjectCycle() {
  670. weak var weakObj1: SwiftCircleObject? = nil, weakObj2: SwiftCircleObject? = nil
  671. autoreleasepool {
  672. let obj1 = SwiftCircleObject(value: [])
  673. let obj2 = SwiftCircleObject(value: [obj1, [obj1]])
  674. obj1.obj = obj2
  675. obj1.array.append(obj2)
  676. weakObj1 = obj1
  677. weakObj2 = obj2
  678. let realm = try! Realm()
  679. try! realm.write {
  680. realm.add(obj1)
  681. }
  682. XCTAssertEqual(obj1.realm, realm)
  683. XCTAssertEqual(obj2.realm, realm)
  684. }
  685. XCTAssertNil(weakObj1)
  686. XCTAssertNil(weakObj2)
  687. }
  688. func testAddOrUpdateNil() {
  689. let realm = try! Realm()
  690. realm.beginWrite()
  691. // Create with all fields nil
  692. let object = SwiftOptionalPrimaryObject()
  693. realm.add(object)
  694. XCTAssertNil(object.id.value)
  695. XCTAssertNil(object.optIntCol.value)
  696. XCTAssertNil(object.optInt8Col.value)
  697. XCTAssertNil(object.optInt16Col.value)
  698. XCTAssertNil(object.optInt32Col.value)
  699. XCTAssertNil(object.optInt64Col.value)
  700. XCTAssertNil(object.optBoolCol.value)
  701. XCTAssertNil(object.optFloatCol.value)
  702. XCTAssertNil(object.optDoubleCol.value)
  703. XCTAssertNil(object.optDateCol)
  704. XCTAssertNil(object.optStringCol)
  705. XCTAssertNil(object.optNSStringCol)
  706. XCTAssertNil(object.optBinaryCol)
  707. XCTAssertNil(object.optObjectCol)
  708. // Try to switch to non-nil
  709. let object2 = SwiftOptionalPrimaryObject()
  710. object2.optIntCol.value = 1
  711. object2.optInt8Col.value = 1
  712. object2.optInt16Col.value = 1
  713. object2.optInt32Col.value = 1
  714. object2.optInt64Col.value = 1
  715. object2.optFloatCol.value = 1
  716. object2.optDoubleCol.value = 1
  717. object2.optBoolCol.value = true
  718. object2.optDateCol = Date()
  719. object2.optStringCol = ""
  720. object2.optNSStringCol = ""
  721. object2.optBinaryCol = Data()
  722. object2.optObjectCol = SwiftBoolObject()
  723. realm.add(object2, update: .all)
  724. XCTAssertNil(object.id.value)
  725. XCTAssertNotNil(object.optIntCol.value)
  726. XCTAssertNotNil(object.optInt8Col.value)
  727. XCTAssertNotNil(object.optInt16Col.value)
  728. XCTAssertNotNil(object.optInt32Col.value)
  729. XCTAssertNotNil(object.optInt64Col.value)
  730. XCTAssertNotNil(object.optBoolCol.value)
  731. XCTAssertNotNil(object.optFloatCol.value)
  732. XCTAssertNotNil(object.optDoubleCol.value)
  733. XCTAssertNotNil(object.optDateCol)
  734. XCTAssertNotNil(object.optStringCol)
  735. XCTAssertNotNil(object.optNSStringCol)
  736. XCTAssertNotNil(object.optBinaryCol)
  737. XCTAssertNotNil(object.optObjectCol)
  738. // Try to switch back to nil
  739. let object3 = SwiftOptionalPrimaryObject()
  740. realm.add(object3, update: .all)
  741. XCTAssertNil(object.id.value)
  742. XCTAssertNil(object.optIntCol.value)
  743. XCTAssertNil(object.optInt8Col.value)
  744. XCTAssertNil(object.optInt16Col.value)
  745. XCTAssertNil(object.optInt32Col.value)
  746. XCTAssertNil(object.optInt64Col.value)
  747. XCTAssertNil(object.optBoolCol.value)
  748. XCTAssertNil(object.optFloatCol.value)
  749. XCTAssertNil(object.optDoubleCol.value)
  750. XCTAssertNil(object.optDateCol)
  751. XCTAssertNil(object.optStringCol)
  752. XCTAssertNil(object.optNSStringCol)
  753. XCTAssertNil(object.optBinaryCol)
  754. XCTAssertNil(object.optObjectCol)
  755. realm.cancelWrite()
  756. }
  757. func testAddOrUpdateModifiedNil() {
  758. let realm = try! Realm()
  759. realm.beginWrite()
  760. // Create with all fields nil
  761. let object = SwiftOptionalPrimaryObject()
  762. realm.add(object)
  763. XCTAssertNil(object.id.value)
  764. XCTAssertNil(object.optIntCol.value)
  765. XCTAssertNil(object.optInt8Col.value)
  766. XCTAssertNil(object.optInt16Col.value)
  767. XCTAssertNil(object.optInt32Col.value)
  768. XCTAssertNil(object.optInt64Col.value)
  769. XCTAssertNil(object.optBoolCol.value)
  770. XCTAssertNil(object.optFloatCol.value)
  771. XCTAssertNil(object.optDoubleCol.value)
  772. XCTAssertNil(object.optDateCol)
  773. XCTAssertNil(object.optStringCol)
  774. XCTAssertNil(object.optNSStringCol)
  775. XCTAssertNil(object.optBinaryCol)
  776. XCTAssertNil(object.optObjectCol)
  777. // Try to switch to non-nil
  778. let object2 = SwiftOptionalPrimaryObject()
  779. object2.optIntCol.value = 1
  780. object2.optInt8Col.value = 1
  781. object2.optInt16Col.value = 1
  782. object2.optInt32Col.value = 1
  783. object2.optInt64Col.value = 1
  784. object2.optFloatCol.value = 1
  785. object2.optDoubleCol.value = 1
  786. object2.optBoolCol.value = true
  787. object2.optDateCol = Date()
  788. object2.optStringCol = ""
  789. object2.optNSStringCol = ""
  790. object2.optBinaryCol = Data()
  791. object2.optObjectCol = SwiftBoolObject()
  792. realm.add(object2, update: .modified)
  793. XCTAssertNil(object.id.value)
  794. XCTAssertNotNil(object.optIntCol.value)
  795. XCTAssertNotNil(object.optInt8Col.value)
  796. XCTAssertNotNil(object.optInt16Col.value)
  797. XCTAssertNotNil(object.optInt32Col.value)
  798. XCTAssertNotNil(object.optInt64Col.value)
  799. XCTAssertNotNil(object.optBoolCol.value)
  800. XCTAssertNotNil(object.optFloatCol.value)
  801. XCTAssertNotNil(object.optDoubleCol.value)
  802. XCTAssertNotNil(object.optDateCol)
  803. XCTAssertNotNil(object.optStringCol)
  804. XCTAssertNotNil(object.optNSStringCol)
  805. XCTAssertNotNil(object.optBinaryCol)
  806. XCTAssertNotNil(object.optObjectCol)
  807. // Try to switch back to nil
  808. let object3 = SwiftOptionalPrimaryObject()
  809. realm.add(object3, update: .modified)
  810. XCTAssertNil(object.id.value)
  811. XCTAssertNil(object.optIntCol.value)
  812. XCTAssertNil(object.optInt8Col.value)
  813. XCTAssertNil(object.optInt16Col.value)
  814. XCTAssertNil(object.optInt32Col.value)
  815. XCTAssertNil(object.optInt64Col.value)
  816. XCTAssertNil(object.optBoolCol.value)
  817. XCTAssertNil(object.optFloatCol.value)
  818. XCTAssertNil(object.optDoubleCol.value)
  819. XCTAssertNil(object.optDateCol)
  820. XCTAssertNil(object.optStringCol)
  821. XCTAssertNil(object.optNSStringCol)
  822. XCTAssertNil(object.optBinaryCol)
  823. XCTAssertNil(object.optObjectCol)
  824. realm.cancelWrite()
  825. }
  826. /// If a Swift class declares generic properties before non-generic ones, the properties
  827. /// should be registered in order and creation from an array of values should work.
  828. func testProperOrderingOfProperties() {
  829. let v: [Any] = [
  830. // Superclass's columns
  831. [["intCol": 42], ["intCol": 9001]],
  832. 100,
  833. 200,
  834. // Class's columns
  835. 1,
  836. [["stringCol": "hello"], ["stringCol": "world"]],
  837. 2,
  838. [["stringCol": "goodbye"], ["stringCol": "cruel"], ["stringCol": "world"]],
  839. NSNull(),
  840. 3,
  841. 300]
  842. let object = SwiftGenericPropsOrderingObject(value: v)
  843. XCTAssertEqual(object.firstNumber, 1)
  844. XCTAssertEqual(object.secondNumber, 2)
  845. XCTAssertEqual(object.thirdNumber, 3)
  846. XCTAssertTrue(object.firstArray.count == 2)
  847. XCTAssertEqual(object.firstArray[0].stringCol, "hello")
  848. XCTAssertEqual(object.firstArray[1].stringCol, "world")
  849. XCTAssertTrue(object.secondArray.count == 3)
  850. XCTAssertEqual(object.secondArray[0].stringCol, "goodbye")
  851. XCTAssertEqual(object.secondArray[1].stringCol, "cruel")
  852. XCTAssertEqual(object.secondArray[2].stringCol, "world")
  853. XCTAssertEqual(object.firstOptionalNumber.value, nil)
  854. XCTAssertEqual(object.secondOptionalNumber.value, 300)
  855. XCTAssertTrue(object.parentFirstList.count == 2)
  856. XCTAssertEqual(object.parentFirstList[0].intCol, 42)
  857. XCTAssertEqual(object.parentFirstList[1].intCol, 9001)
  858. XCTAssertEqual(object.parentFirstNumber, 100)
  859. XCTAssertEqual(object.parentSecondNumber, 200)
  860. XCTAssertTrue(object.firstLinking.count == 0)
  861. XCTAssertTrue(object.secondLinking.count == 0)
  862. }
  863. func testPrivateOptionalNonobjcString() {
  864. let realm = try! Realm()
  865. try! realm.write {
  866. let obj = ObjectWithPrivateOptionals()
  867. obj.value = 5
  868. realm.add(obj)
  869. XCTAssertEqual(realm.objects(ObjectWithPrivateOptionals.self).first!.value, 5)
  870. }
  871. }
  872. // MARK: Private utilities
  873. private func verifySwiftObjectWithArrayLiteral(_ object: SwiftObject, array: [Any], boolObjectValue: Bool,
  874. boolObjectListValues: [Bool]) {
  875. XCTAssertEqual(object.boolCol, (array[0] as! Bool))
  876. XCTAssertEqual(object.intCol, (array[1] as! Int))
  877. XCTAssertEqual(object.intEnumCol, IntEnum(rawValue: array[2] as! Int))
  878. XCTAssertEqual(object.floatCol, (array[3] as! NSNumber).floatValue)
  879. XCTAssertEqual(object.doubleCol, (array[4] as! Double))
  880. XCTAssertEqual(object.stringCol, (array[5] as! String))
  881. XCTAssertEqual(object.binaryCol, (array[6] as! Data))
  882. XCTAssertEqual(object.dateCol, (array[7] as! Date))
  883. XCTAssertEqual(object.objectCol!.boolCol, boolObjectValue)
  884. XCTAssertEqual(object.arrayCol.count, boolObjectListValues.count)
  885. for i in 0..<boolObjectListValues.count {
  886. XCTAssertEqual(object.arrayCol[i].boolCol, boolObjectListValues[i])
  887. }
  888. }
  889. private func verifySwiftObjectWithDictionaryLiteral(_ object: SwiftObject, dictionary: [String: Any],
  890. boolObjectValue: Bool, boolObjectListValues: [Bool]) {
  891. XCTAssertEqual(object.boolCol, (dictionary["boolCol"] as! Bool))
  892. XCTAssertEqual(object.intCol, (dictionary["intCol"] as! Int))
  893. //XCTAssertEqual(object.floatCol, (dictionary["floatCol"] as! Float)) // FIXME: crashes with swift 3.2
  894. XCTAssertEqual(object.doubleCol, (dictionary["doubleCol"] as! Double))
  895. XCTAssertEqual(object.stringCol, (dictionary["stringCol"] as! String))
  896. XCTAssertEqual(object.binaryCol, (dictionary["binaryCol"] as! Data))
  897. XCTAssertEqual(object.dateCol, (dictionary["dateCol"] as! Date))
  898. XCTAssertEqual(object.objectCol!.boolCol, boolObjectValue)
  899. XCTAssertEqual(object.arrayCol.count, boolObjectListValues.count)
  900. for i in 0..<boolObjectListValues.count {
  901. XCTAssertEqual(object.arrayCol[i].boolCol, boolObjectListValues[i])
  902. }
  903. }
  904. private func verifySwiftOptionalObjectWithDictionaryLiteral(_ object: SwiftOptionalDefaultValuesObject,
  905. dictionary: [String: Any],
  906. boolObjectValue: Bool?) {
  907. XCTAssertEqual(object.optBoolCol.value, (dictionary["optBoolCol"] as! Bool?))
  908. XCTAssertEqual(object.optIntCol.value, (dictionary["optIntCol"] as! Int?))
  909. XCTAssertEqual(object.optInt8Col.value,
  910. ((dictionary["optInt8Col"] as! NSNumber?)?.int8Value).map({Int8($0)}))
  911. XCTAssertEqual(object.optInt16Col.value,
  912. ((dictionary["optInt16Col"] as! NSNumber?)?.int16Value).map({Int16($0)}))
  913. XCTAssertEqual(object.optInt32Col.value,
  914. ((dictionary["optInt32Col"] as! NSNumber?)?.int32Value).map({Int32($0)}))
  915. XCTAssertEqual(object.optInt64Col.value, (dictionary["optInt64Col"] as! NSNumber?)?.int64Value)
  916. XCTAssertEqual(object.optFloatCol.value, (dictionary["optFloatCol"] as! Float?))
  917. XCTAssertEqual(object.optDoubleCol.value, (dictionary["optDoubleCol"] as! Double?))
  918. XCTAssertEqual(object.optStringCol, (dictionary["optStringCol"] as! String?))
  919. XCTAssertEqual(object.optNSStringCol, (dictionary["optNSStringCol"] as! NSString))
  920. XCTAssertEqual(object.optBinaryCol, (dictionary["optBinaryCol"] as! Data?))
  921. XCTAssertEqual(object.optDateCol, (dictionary["optDateCol"] as! Date?))
  922. XCTAssertEqual(object.optObjectCol?.boolCol, boolObjectValue)
  923. }
  924. private func defaultSwiftObjectValuesWithReplacements(_ replace: [String: Any]) -> [String: Any] {
  925. var valueDict = SwiftObject.defaultValues()
  926. for (key, value) in replace {
  927. valueDict[key] = value
  928. }
  929. return valueDict
  930. }
  931. // return an array of valid values that can be used to initialize each type
  932. // swiftlint:disable:next cyclomatic_complexity
  933. private func validValuesForSwiftObjectType(_ type: PropertyType, _ array: Bool) -> [Any] {
  934. try! Realm().beginWrite()
  935. let persistedObject = try! Realm().create(SwiftBoolObject.self, value: [true])
  936. try! Realm().commitWrite()
  937. if array {
  938. return [
  939. [[true], [false]],
  940. [["boolCol": true], ["boolCol": false]],
  941. [SwiftBoolObject(value: [true]), SwiftBoolObject(value: [false])],
  942. [persistedObject, [false]]
  943. ]
  944. }
  945. switch type {
  946. case .bool: return [true, NSNumber(value: 0 as Int), NSNumber(value: 1 as Int)]
  947. case .int: return [NSNumber(value: 1 as Int)]
  948. case .float: return [NSNumber(value: 1 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  949. case .double: return [NSNumber(value: 1 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  950. case .string: return ["b"]
  951. case .data: return ["b".data(using: String.Encoding.utf8, allowLossyConversion: false)!]
  952. case .date: return [Date(timeIntervalSince1970: 2)]
  953. case .object: return [[true], ["boolCol": true], SwiftBoolObject(value: [true]), persistedObject]
  954. case .any: XCTFail("not supported")
  955. case .linkingObjects: XCTFail("not supported")
  956. }
  957. return []
  958. }
  959. // swiftlint:disable:next cyclomatic_complexity
  960. private func invalidValuesForSwiftObjectType(_ type: PropertyType, _ array: Bool) -> [Any] {
  961. try! Realm().beginWrite()
  962. let persistedObject = try! Realm().create(SwiftIntObject.self)
  963. try! Realm().commitWrite()
  964. if array {
  965. return ["invalid", [["a"]], [["boolCol": "a"]], [[SwiftIntObject()]], [[persistedObject]]]
  966. }
  967. switch type {
  968. case .bool: return ["invalid", NSNumber(value: 2 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  969. case .int: return ["invalid", NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  970. case .float: return ["invalid", true, false]
  971. case .double: return ["invalid", true, false]
  972. case .string: return [0x197A71D, true, false]
  973. case .data: return ["invalid"]
  974. case .date: return ["invalid"]
  975. case .object: return ["invalid", ["a"], ["boolCol": "a"], SwiftIntObject()]
  976. case .any: XCTFail("not supported")
  977. case .linkingObjects: XCTFail("not supported")
  978. }
  979. return []
  980. }
  981. }