ObjectCreationTests.swift 46 KB

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