ObjectCreationTests.swift 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  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. let realm = try! Realm()
  295. realm.beginWrite()
  296. let objectWithNestedObjects = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["p1", ["p1", 12],
  297. [standalone]])
  298. try! realm.commitWrite()
  299. let stringObjects = realm.objects(SwiftPrimaryStringObject.self)
  300. XCTAssertEqual(stringObjects.count, 2)
  301. let p0 = realm.object(ofType: SwiftPrimaryStringObject.self, forPrimaryKey: "p0")
  302. let p1 = realm.object(ofType: SwiftPrimaryStringObject.self, forPrimaryKey: "p1")
  303. // standalone object should be copied into the realm, not added directly
  304. XCTAssertNil(standalone.realm)
  305. XCTAssertNotEqual(standalone, p0)
  306. XCTAssertEqual(objectWithNestedObjects.object!, p1)
  307. XCTAssertEqual(objectWithNestedObjects.objects.first!, p0)
  308. let standalone1 = SwiftPrimaryStringObject(value: ["p3", 11])
  309. realm.beginWrite()
  310. assertThrows(realm.create(SwiftLinkToPrimaryStringObject.self, value: ["p3", ["p3", 11], [standalone1]]),
  311. "Should throw with duplicate primary key")
  312. try! realm.commitWrite()
  313. }
  314. func testUpdateWithNestedObjects() {
  315. let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
  316. try! Realm().beginWrite()
  317. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
  318. [["primary", 12]]], update: .all)
  319. try! Realm().commitWrite()
  320. let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
  321. XCTAssertEqual(stringObjects.count, 1)
  322. let persistedObject = object.object!
  323. XCTAssertEqual(persistedObject.intCol, 12)
  324. XCTAssertNil(standalone.realm) // the standalone object should be copied, rather than added, to the realm
  325. XCTAssertEqual(object.object!, persistedObject)
  326. XCTAssertEqual(object.objects.first!, persistedObject)
  327. }
  328. func testUpdateChangedWithNestedObjects() {
  329. let standalone = SwiftPrimaryStringObject(value: ["primary", 11])
  330. try! Realm().beginWrite()
  331. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["otherPrimary", ["primary", 12],
  332. [["primary", 12]]], update: .modified)
  333. try! Realm().commitWrite()
  334. let stringObjects = try! Realm().objects(SwiftPrimaryStringObject.self)
  335. XCTAssertEqual(stringObjects.count, 1)
  336. let persistedObject = object.object!
  337. XCTAssertEqual(persistedObject.intCol, 12)
  338. XCTAssertNil(standalone.realm) // the standalone object should be copied, rather than added, to the realm
  339. XCTAssertEqual(object.object!, persistedObject)
  340. XCTAssertEqual(object.objects.first!, persistedObject)
  341. }
  342. func testCreateWithObjectsFromAnotherRealm() {
  343. let values: [String: Any] = [
  344. "boolCol": true,
  345. "intCol": 1,
  346. "floatCol": 1.1 as Float,
  347. "doubleCol": 11.1,
  348. "stringCol": "b",
  349. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  350. "dateCol": Date(timeIntervalSince1970: 2),
  351. "objectCol": SwiftBoolObject(value: [true]),
  352. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  353. ]
  354. realmWithTestPath().beginWrite()
  355. let otherRealmObject = realmWithTestPath().create(SwiftObject.self, value: values)
  356. try! realmWithTestPath().commitWrite()
  357. try! Realm().beginWrite()
  358. let object = try! Realm().create(SwiftObject.self, value: otherRealmObject)
  359. try! Realm().commitWrite()
  360. XCTAssertNotEqual(otherRealmObject, object)
  361. verifySwiftObjectWithDictionaryLiteral(object, dictionary: values, boolObjectValue: true,
  362. boolObjectListValues: [true, false])
  363. }
  364. func testCreateWithDeeplyNestedObjectsFromAnotherRealm() {
  365. let values: [String: Any] = [
  366. "boolCol": true,
  367. "intCol": 1,
  368. "floatCol": 1.1 as Float,
  369. "doubleCol": 11.1,
  370. "stringCol": "b",
  371. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  372. "dateCol": Date(timeIntervalSince1970: 2),
  373. "objectCol": SwiftBoolObject(value: [true]),
  374. "arrayCol": [SwiftBoolObject(value: [true]), SwiftBoolObject()]
  375. ]
  376. let realmA = realmWithTestPath()
  377. let realmB = try! Realm()
  378. var realmAObject: SwiftListOfSwiftObject?
  379. try! realmA.write {
  380. let array = [SwiftObject(value: values), SwiftObject(value: values)]
  381. realmAObject = realmA.create(SwiftListOfSwiftObject.self, value: ["array": array])
  382. }
  383. var realmBObject: SwiftListOfSwiftObject!
  384. try! realmB.write {
  385. realmBObject = realmB.create(SwiftListOfSwiftObject.self, value: realmAObject!)
  386. }
  387. XCTAssertNotEqual(realmAObject, realmBObject)
  388. XCTAssertEqual(realmBObject.array.count, 2)
  389. for swiftObject in realmBObject.array {
  390. verifySwiftObjectWithDictionaryLiteral(swiftObject, dictionary: values, boolObjectValue: true,
  391. boolObjectListValues: [true, false])
  392. }
  393. }
  394. func testUpdateWithObjectsFromAnotherRealm() {
  395. realmWithTestPath().beginWrite()
  396. let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self,
  397. value: ["primary", NSNull(), [["2", 2], ["4", 4]]])
  398. try! realmWithTestPath().commitWrite()
  399. try! Realm().beginWrite()
  400. try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
  401. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .all)
  402. try! Realm().commitWrite()
  403. XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
  404. XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1)
  405. XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4)
  406. }
  407. func testUpdateChangedWithObjectsFromAnotherRealm() {
  408. realmWithTestPath().beginWrite()
  409. let otherRealmObject = realmWithTestPath().create(SwiftLinkToPrimaryStringObject.self,
  410. value: ["primary", NSNull(), [["2", 2], ["4", 4]]])
  411. try! realmWithTestPath().commitWrite()
  412. try! Realm().beginWrite()
  413. try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: ["primary", ["10", 10], [["11", 11]]])
  414. let object = try! Realm().create(SwiftLinkToPrimaryStringObject.self, value: otherRealmObject, update: .modified)
  415. try! Realm().commitWrite()
  416. XCTAssertNotEqual(otherRealmObject, object) // the object from the other realm should be copied into this realm
  417. XCTAssertEqual(try! Realm().objects(SwiftLinkToPrimaryStringObject.self).count, 1)
  418. XCTAssertEqual(try! Realm().objects(SwiftPrimaryStringObject.self).count, 4)
  419. }
  420. func testCreateWithNSNullLinks() {
  421. let values: [String: Any] = [
  422. "boolCol": true,
  423. "intCol": 1,
  424. "floatCol": 1.1,
  425. "doubleCol": 11.1,
  426. "stringCol": "b",
  427. "binaryCol": "b".data(using: String.Encoding.utf8)!,
  428. "dateCol": Date(timeIntervalSince1970: 2),
  429. "objectCol": NSNull(),
  430. "arrayCol": NSNull()
  431. ]
  432. realmWithTestPath().beginWrite()
  433. let object = realmWithTestPath().create(SwiftObject.self, value: values)
  434. try! realmWithTestPath().commitWrite()
  435. XCTAssert(object.objectCol == nil) // XCTAssertNil caused a NULL deref inside _swift_getClass
  436. XCTAssertEqual(object.arrayCol.count, 0)
  437. }
  438. func testCreateWithObjcName() {
  439. let realm = try! Realm()
  440. try! realm.write {
  441. let object = realm.create(SwiftObjcRenamedObject.self)
  442. object.stringCol = "string"
  443. }
  444. XCTAssertEqual(realm.objects(SwiftObjcRenamedObject.self).count, 1)
  445. try! realm.write {
  446. realm.delete(realm.objects(SwiftObjcRenamedObject.self))
  447. }
  448. }
  449. func testCreateWithDifferentObjcName() {
  450. let realm = try! Realm()
  451. try! realm.write {
  452. let object = realm.create(SwiftObjcArbitrarilyRenamedObject.self)
  453. object.boolCol = true
  454. }
  455. XCTAssertEqual(realm.objects(SwiftObjcArbitrarilyRenamedObject.self).count, 1)
  456. try! realm.write {
  457. realm.delete(realm.objects(SwiftObjcArbitrarilyRenamedObject.self))
  458. }
  459. }
  460. func testCreateOrUpdateNil() {
  461. let realm = try! Realm()
  462. realm.beginWrite()
  463. // Create with all fields nil
  464. let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
  465. XCTAssertNil(object.id.value)
  466. XCTAssertNil(object.optIntCol.value)
  467. XCTAssertNil(object.optInt8Col.value)
  468. XCTAssertNil(object.optInt16Col.value)
  469. XCTAssertNil(object.optInt32Col.value)
  470. XCTAssertNil(object.optInt64Col.value)
  471. XCTAssertNil(object.optBoolCol.value)
  472. XCTAssertNil(object.optFloatCol.value)
  473. XCTAssertNil(object.optDoubleCol.value)
  474. XCTAssertNil(object.optDateCol)
  475. XCTAssertNil(object.optStringCol)
  476. XCTAssertNil(object.optNSStringCol)
  477. XCTAssertNil(object.optBinaryCol)
  478. XCTAssertNil(object.optObjectCol)
  479. // Try to switch to non-nil
  480. let object2 = SwiftOptionalPrimaryObject()
  481. object2.optIntCol.value = 1
  482. object2.optInt8Col.value = 1
  483. object2.optInt16Col.value = 1
  484. object2.optInt32Col.value = 1
  485. object2.optInt64Col.value = 1
  486. object2.optFloatCol.value = 1
  487. object2.optDoubleCol.value = 1
  488. object2.optBoolCol.value = true
  489. object2.optDateCol = Date()
  490. object2.optStringCol = ""
  491. object2.optNSStringCol = ""
  492. object2.optBinaryCol = Data()
  493. object2.optObjectCol = SwiftBoolObject()
  494. realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .all)
  495. XCTAssertNil(object.id.value)
  496. XCTAssertNotNil(object.optIntCol.value)
  497. XCTAssertNotNil(object.optInt8Col.value)
  498. XCTAssertNotNil(object.optInt16Col.value)
  499. XCTAssertNotNil(object.optInt32Col.value)
  500. XCTAssertNotNil(object.optInt64Col.value)
  501. XCTAssertNotNil(object.optBoolCol.value)
  502. XCTAssertNotNil(object.optFloatCol.value)
  503. XCTAssertNotNil(object.optDoubleCol.value)
  504. XCTAssertNotNil(object.optDateCol)
  505. XCTAssertNotNil(object.optStringCol)
  506. XCTAssertNotNil(object.optNSStringCol)
  507. XCTAssertNotNil(object.optBinaryCol)
  508. XCTAssertNotNil(object.optObjectCol)
  509. // Try to switch back to nil
  510. realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .all)
  511. XCTAssertNil(object.id.value)
  512. XCTAssertNil(object.optIntCol.value)
  513. XCTAssertNil(object.optInt8Col.value)
  514. XCTAssertNil(object.optInt16Col.value)
  515. XCTAssertNil(object.optInt32Col.value)
  516. XCTAssertNil(object.optInt64Col.value)
  517. XCTAssertNil(object.optBoolCol.value)
  518. XCTAssertNil(object.optFloatCol.value)
  519. XCTAssertNil(object.optDoubleCol.value)
  520. XCTAssertNil(object.optDateCol)
  521. XCTAssertNil(object.optStringCol)
  522. XCTAssertNil(object.optNSStringCol)
  523. XCTAssertNil(object.optBinaryCol)
  524. XCTAssertNil(object.optObjectCol)
  525. realm.cancelWrite()
  526. }
  527. func testCreateOrUpdateModifiedNil() {
  528. let realm = try! Realm()
  529. realm.beginWrite()
  530. // Create with all fields nil
  531. let object = realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
  532. XCTAssertNil(object.id.value)
  533. XCTAssertNil(object.optIntCol.value)
  534. XCTAssertNil(object.optInt8Col.value)
  535. XCTAssertNil(object.optInt16Col.value)
  536. XCTAssertNil(object.optInt32Col.value)
  537. XCTAssertNil(object.optInt64Col.value)
  538. XCTAssertNil(object.optBoolCol.value)
  539. XCTAssertNil(object.optFloatCol.value)
  540. XCTAssertNil(object.optDoubleCol.value)
  541. XCTAssertNil(object.optDateCol)
  542. XCTAssertNil(object.optStringCol)
  543. XCTAssertNil(object.optNSStringCol)
  544. XCTAssertNil(object.optBinaryCol)
  545. XCTAssertNil(object.optObjectCol)
  546. // Try to switch to non-nil
  547. let object2 = SwiftOptionalPrimaryObject()
  548. object2.optIntCol.value = 1
  549. object2.optInt8Col.value = 1
  550. object2.optInt16Col.value = 1
  551. object2.optInt32Col.value = 1
  552. object2.optInt64Col.value = 1
  553. object2.optFloatCol.value = 1
  554. object2.optDoubleCol.value = 1
  555. object2.optBoolCol.value = true
  556. object2.optDateCol = Date()
  557. object2.optStringCol = ""
  558. object2.optNSStringCol = ""
  559. object2.optBinaryCol = Data()
  560. object2.optObjectCol = SwiftBoolObject()
  561. realm.create(SwiftOptionalPrimaryObject.self, value: object2, update: .modified)
  562. XCTAssertNil(object.id.value)
  563. XCTAssertNotNil(object.optIntCol.value)
  564. XCTAssertNotNil(object.optInt8Col.value)
  565. XCTAssertNotNil(object.optInt16Col.value)
  566. XCTAssertNotNil(object.optInt32Col.value)
  567. XCTAssertNotNil(object.optInt64Col.value)
  568. XCTAssertNotNil(object.optBoolCol.value)
  569. XCTAssertNotNil(object.optFloatCol.value)
  570. XCTAssertNotNil(object.optDoubleCol.value)
  571. XCTAssertNotNil(object.optDateCol)
  572. XCTAssertNotNil(object.optStringCol)
  573. XCTAssertNotNil(object.optNSStringCol)
  574. XCTAssertNotNil(object.optBinaryCol)
  575. XCTAssertNotNil(object.optObjectCol)
  576. // Try to switch back to nil
  577. realm.create(SwiftOptionalPrimaryObject.self, value: SwiftOptionalPrimaryObject(), update: .modified)
  578. XCTAssertNil(object.id.value)
  579. XCTAssertNil(object.optIntCol.value)
  580. XCTAssertNil(object.optInt8Col.value)
  581. XCTAssertNil(object.optInt16Col.value)
  582. XCTAssertNil(object.optInt32Col.value)
  583. XCTAssertNil(object.optInt64Col.value)
  584. XCTAssertNil(object.optBoolCol.value)
  585. XCTAssertNil(object.optFloatCol.value)
  586. XCTAssertNil(object.optDoubleCol.value)
  587. XCTAssertNil(object.optDateCol)
  588. XCTAssertNil(object.optStringCol)
  589. XCTAssertNil(object.optNSStringCol)
  590. XCTAssertNil(object.optBinaryCol)
  591. XCTAssertNil(object.optObjectCol)
  592. realm.cancelWrite()
  593. }
  594. func testCreateOrUpdateDynamicUnmanagedType() {
  595. let realm = try! Realm()
  596. let unmanagedValue = SwiftOptionalPrimaryObject()
  597. // Shouldn't throw.
  598. realm.beginWrite()
  599. _ = realm.create(type(of: unmanagedValue), value: unmanagedValue, update: .modified)
  600. realm.cancelWrite()
  601. }
  602. func testCreateOrUpdateDynamicManagedType() {
  603. let realm = try! Realm()
  604. let managedValue = SwiftOptionalPrimaryObject()
  605. try! realm.write {
  606. realm.add(managedValue)
  607. }
  608. // Shouldn't throw.
  609. realm.beginWrite()
  610. _ = realm.create(type(of: managedValue), value: managedValue, update: .all)
  611. realm.cancelWrite()
  612. }
  613. func testCreateOrUpdateModifiedDynamicManagedType() {
  614. let realm = try! Realm()
  615. let managedValue = SwiftOptionalPrimaryObject()
  616. try! realm.write {
  617. realm.add(managedValue)
  618. }
  619. // Shouldn't throw.
  620. realm.beginWrite()
  621. _ = realm.create(type(of: managedValue), value: managedValue, update: .modified)
  622. realm.cancelWrite()
  623. }
  624. func testCreateOrUpdateWithMismatchedStaticAndDynamicTypes() {
  625. let realm = try! Realm()
  626. let obj: Object = SwiftOptionalPrimaryObject()
  627. try! realm.write {
  628. let obj2 = realm.create(type(of: obj), value: obj)
  629. XCTAssertEqual(obj2.objectSchema.className, "SwiftOptionalPrimaryObject")
  630. let obj3 = realm.create(type(of: obj), value: obj, update: .all)
  631. XCTAssertEqual(obj3.objectSchema.className, "SwiftOptionalPrimaryObject")
  632. }
  633. }
  634. // test null object
  635. // test null list
  636. // MARK: Add tests
  637. func testAddWithExisingNestedObjects() {
  638. try! Realm().beginWrite()
  639. let existingObject = try! Realm().create(SwiftBoolObject.self)
  640. try! Realm().commitWrite()
  641. try! Realm().beginWrite()
  642. let object = SwiftObject(value: ["objectCol": existingObject])
  643. try! Realm().add(object)
  644. try! Realm().commitWrite()
  645. XCTAssertNotNil(object.realm)
  646. assertEqual(object.objectCol, existingObject)
  647. }
  648. func testAddAndUpdateWithExisingNestedObjects() {
  649. try! Realm().beginWrite()
  650. let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1])
  651. try! Realm().commitWrite()
  652. try! Realm().beginWrite()
  653. let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
  654. try! Realm().add(object, update: .all)
  655. try! Realm().commitWrite()
  656. XCTAssertNotNil(object.realm)
  657. XCTAssertEqual(object.object!, existingObject) // the existing object should be updated
  658. XCTAssertEqual(existingObject.intCol, 2)
  659. }
  660. func testAddAndUpdateChangedWithExisingNestedObjects() {
  661. try! Realm().beginWrite()
  662. let existingObject = try! Realm().create(SwiftPrimaryStringObject.self, value: ["primary", 1])
  663. try! Realm().commitWrite()
  664. try! Realm().beginWrite()
  665. let object = SwiftLinkToPrimaryStringObject(value: ["primary", ["primary", 2], []])
  666. try! Realm().add(object, update: .modified)
  667. try! Realm().commitWrite()
  668. XCTAssertNotNil(object.realm)
  669. XCTAssertEqual(object.object!, existingObject) // the existing object should be updated
  670. XCTAssertEqual(existingObject.intCol, 2)
  671. }
  672. func testAddObjectCycle() {
  673. weak var weakObj1: SwiftCircleObject? = nil, weakObj2: SwiftCircleObject? = nil
  674. autoreleasepool {
  675. let obj1 = SwiftCircleObject(value: [])
  676. let obj2 = SwiftCircleObject(value: [obj1, [obj1]])
  677. obj1.obj = obj2
  678. obj1.array.append(obj2)
  679. weakObj1 = obj1
  680. weakObj2 = obj2
  681. let realm = try! Realm()
  682. try! realm.write {
  683. realm.add(obj1)
  684. }
  685. XCTAssertEqual(obj1.realm, realm)
  686. XCTAssertEqual(obj2.realm, realm)
  687. }
  688. XCTAssertNil(weakObj1)
  689. XCTAssertNil(weakObj2)
  690. }
  691. func testAddOrUpdateNil() {
  692. let realm = try! Realm()
  693. realm.beginWrite()
  694. // Create with all fields nil
  695. let object = SwiftOptionalPrimaryObject()
  696. realm.add(object)
  697. XCTAssertNil(object.id.value)
  698. XCTAssertNil(object.optIntCol.value)
  699. XCTAssertNil(object.optInt8Col.value)
  700. XCTAssertNil(object.optInt16Col.value)
  701. XCTAssertNil(object.optInt32Col.value)
  702. XCTAssertNil(object.optInt64Col.value)
  703. XCTAssertNil(object.optBoolCol.value)
  704. XCTAssertNil(object.optFloatCol.value)
  705. XCTAssertNil(object.optDoubleCol.value)
  706. XCTAssertNil(object.optDateCol)
  707. XCTAssertNil(object.optStringCol)
  708. XCTAssertNil(object.optNSStringCol)
  709. XCTAssertNil(object.optBinaryCol)
  710. XCTAssertNil(object.optObjectCol)
  711. // Try to switch to non-nil
  712. let object2 = SwiftOptionalPrimaryObject()
  713. object2.optIntCol.value = 1
  714. object2.optInt8Col.value = 1
  715. object2.optInt16Col.value = 1
  716. object2.optInt32Col.value = 1
  717. object2.optInt64Col.value = 1
  718. object2.optFloatCol.value = 1
  719. object2.optDoubleCol.value = 1
  720. object2.optBoolCol.value = true
  721. object2.optDateCol = Date()
  722. object2.optStringCol = ""
  723. object2.optNSStringCol = ""
  724. object2.optBinaryCol = Data()
  725. object2.optObjectCol = SwiftBoolObject()
  726. realm.add(object2, update: .all)
  727. XCTAssertNil(object.id.value)
  728. XCTAssertNotNil(object.optIntCol.value)
  729. XCTAssertNotNil(object.optInt8Col.value)
  730. XCTAssertNotNil(object.optInt16Col.value)
  731. XCTAssertNotNil(object.optInt32Col.value)
  732. XCTAssertNotNil(object.optInt64Col.value)
  733. XCTAssertNotNil(object.optBoolCol.value)
  734. XCTAssertNotNil(object.optFloatCol.value)
  735. XCTAssertNotNil(object.optDoubleCol.value)
  736. XCTAssertNotNil(object.optDateCol)
  737. XCTAssertNotNil(object.optStringCol)
  738. XCTAssertNotNil(object.optNSStringCol)
  739. XCTAssertNotNil(object.optBinaryCol)
  740. XCTAssertNotNil(object.optObjectCol)
  741. // Try to switch back to nil
  742. let object3 = SwiftOptionalPrimaryObject()
  743. realm.add(object3, update: .all)
  744. XCTAssertNil(object.id.value)
  745. XCTAssertNil(object.optIntCol.value)
  746. XCTAssertNil(object.optInt8Col.value)
  747. XCTAssertNil(object.optInt16Col.value)
  748. XCTAssertNil(object.optInt32Col.value)
  749. XCTAssertNil(object.optInt64Col.value)
  750. XCTAssertNil(object.optBoolCol.value)
  751. XCTAssertNil(object.optFloatCol.value)
  752. XCTAssertNil(object.optDoubleCol.value)
  753. XCTAssertNil(object.optDateCol)
  754. XCTAssertNil(object.optStringCol)
  755. XCTAssertNil(object.optNSStringCol)
  756. XCTAssertNil(object.optBinaryCol)
  757. XCTAssertNil(object.optObjectCol)
  758. realm.cancelWrite()
  759. }
  760. func testAddOrUpdateModifiedNil() {
  761. let realm = try! Realm()
  762. realm.beginWrite()
  763. // Create with all fields nil
  764. let object = SwiftOptionalPrimaryObject()
  765. realm.add(object)
  766. XCTAssertNil(object.id.value)
  767. XCTAssertNil(object.optIntCol.value)
  768. XCTAssertNil(object.optInt8Col.value)
  769. XCTAssertNil(object.optInt16Col.value)
  770. XCTAssertNil(object.optInt32Col.value)
  771. XCTAssertNil(object.optInt64Col.value)
  772. XCTAssertNil(object.optBoolCol.value)
  773. XCTAssertNil(object.optFloatCol.value)
  774. XCTAssertNil(object.optDoubleCol.value)
  775. XCTAssertNil(object.optDateCol)
  776. XCTAssertNil(object.optStringCol)
  777. XCTAssertNil(object.optNSStringCol)
  778. XCTAssertNil(object.optBinaryCol)
  779. XCTAssertNil(object.optObjectCol)
  780. // Try to switch to non-nil
  781. let object2 = SwiftOptionalPrimaryObject()
  782. object2.optIntCol.value = 1
  783. object2.optInt8Col.value = 1
  784. object2.optInt16Col.value = 1
  785. object2.optInt32Col.value = 1
  786. object2.optInt64Col.value = 1
  787. object2.optFloatCol.value = 1
  788. object2.optDoubleCol.value = 1
  789. object2.optBoolCol.value = true
  790. object2.optDateCol = Date()
  791. object2.optStringCol = ""
  792. object2.optNSStringCol = ""
  793. object2.optBinaryCol = Data()
  794. object2.optObjectCol = SwiftBoolObject()
  795. realm.add(object2, update: .modified)
  796. XCTAssertNil(object.id.value)
  797. XCTAssertNotNil(object.optIntCol.value)
  798. XCTAssertNotNil(object.optInt8Col.value)
  799. XCTAssertNotNil(object.optInt16Col.value)
  800. XCTAssertNotNil(object.optInt32Col.value)
  801. XCTAssertNotNil(object.optInt64Col.value)
  802. XCTAssertNotNil(object.optBoolCol.value)
  803. XCTAssertNotNil(object.optFloatCol.value)
  804. XCTAssertNotNil(object.optDoubleCol.value)
  805. XCTAssertNotNil(object.optDateCol)
  806. XCTAssertNotNil(object.optStringCol)
  807. XCTAssertNotNil(object.optNSStringCol)
  808. XCTAssertNotNil(object.optBinaryCol)
  809. XCTAssertNotNil(object.optObjectCol)
  810. // Try to switch back to nil
  811. let object3 = SwiftOptionalPrimaryObject()
  812. realm.add(object3, update: .modified)
  813. XCTAssertNil(object.id.value)
  814. XCTAssertNil(object.optIntCol.value)
  815. XCTAssertNil(object.optInt8Col.value)
  816. XCTAssertNil(object.optInt16Col.value)
  817. XCTAssertNil(object.optInt32Col.value)
  818. XCTAssertNil(object.optInt64Col.value)
  819. XCTAssertNil(object.optBoolCol.value)
  820. XCTAssertNil(object.optFloatCol.value)
  821. XCTAssertNil(object.optDoubleCol.value)
  822. XCTAssertNil(object.optDateCol)
  823. XCTAssertNil(object.optStringCol)
  824. XCTAssertNil(object.optNSStringCol)
  825. XCTAssertNil(object.optBinaryCol)
  826. XCTAssertNil(object.optObjectCol)
  827. realm.cancelWrite()
  828. }
  829. /// If a Swift class declares generic properties before non-generic ones, the properties
  830. /// should be registered in order and creation from an array of values should work.
  831. func testProperOrderingOfProperties() {
  832. let v: [Any] = [
  833. // Superclass's columns
  834. [["intCol": 42], ["intCol": 9001]],
  835. 100,
  836. 200,
  837. // Class's columns
  838. 1,
  839. [["stringCol": "hello"], ["stringCol": "world"]],
  840. 2,
  841. [["stringCol": "goodbye"], ["stringCol": "cruel"], ["stringCol": "world"]],
  842. NSNull(),
  843. 3,
  844. 300]
  845. let object = SwiftGenericPropsOrderingObject(value: v)
  846. XCTAssertEqual(object.firstNumber, 1)
  847. XCTAssertEqual(object.secondNumber, 2)
  848. XCTAssertEqual(object.thirdNumber, 3)
  849. XCTAssertTrue(object.firstArray.count == 2)
  850. XCTAssertEqual(object.firstArray[0].stringCol, "hello")
  851. XCTAssertEqual(object.firstArray[1].stringCol, "world")
  852. XCTAssertTrue(object.secondArray.count == 3)
  853. XCTAssertEqual(object.secondArray[0].stringCol, "goodbye")
  854. XCTAssertEqual(object.secondArray[1].stringCol, "cruel")
  855. XCTAssertEqual(object.secondArray[2].stringCol, "world")
  856. XCTAssertEqual(object.firstOptionalNumber.value, nil)
  857. XCTAssertEqual(object.secondOptionalNumber.value, 300)
  858. XCTAssertTrue(object.parentFirstList.count == 2)
  859. XCTAssertEqual(object.parentFirstList[0].intCol, 42)
  860. XCTAssertEqual(object.parentFirstList[1].intCol, 9001)
  861. XCTAssertEqual(object.parentFirstNumber, 100)
  862. XCTAssertEqual(object.parentSecondNumber, 200)
  863. XCTAssertTrue(object.firstLinking.count == 0)
  864. XCTAssertTrue(object.secondLinking.count == 0)
  865. }
  866. func testPrivateOptionalNonobjcString() {
  867. let realm = try! Realm()
  868. try! realm.write {
  869. let obj = ObjectWithPrivateOptionals()
  870. obj.value = 5
  871. realm.add(obj)
  872. XCTAssertEqual(realm.objects(ObjectWithPrivateOptionals.self).first!.value, 5)
  873. }
  874. }
  875. // MARK: Private utilities
  876. private func verifySwiftObjectWithArrayLiteral(_ object: SwiftObject, array: [Any], boolObjectValue: Bool,
  877. boolObjectListValues: [Bool]) {
  878. XCTAssertEqual(object.boolCol, (array[0] as! Bool))
  879. XCTAssertEqual(object.intCol, (array[1] as! Int))
  880. XCTAssertEqual(object.intEnumCol, IntEnum(rawValue: array[2] as! Int))
  881. XCTAssertEqual(object.floatCol, (array[3] as! NSNumber).floatValue)
  882. XCTAssertEqual(object.doubleCol, (array[4] as! Double))
  883. XCTAssertEqual(object.stringCol, (array[5] as! String))
  884. XCTAssertEqual(object.binaryCol, (array[6] as! Data))
  885. XCTAssertEqual(object.dateCol, (array[7] as! Date))
  886. XCTAssertEqual(object.objectCol!.boolCol, boolObjectValue)
  887. XCTAssertEqual(object.arrayCol.count, boolObjectListValues.count)
  888. for i in 0..<boolObjectListValues.count {
  889. XCTAssertEqual(object.arrayCol[i].boolCol, boolObjectListValues[i])
  890. }
  891. }
  892. private func verifySwiftObjectWithDictionaryLiteral(_ object: SwiftObject, dictionary: [String: Any],
  893. boolObjectValue: Bool, boolObjectListValues: [Bool]) {
  894. XCTAssertEqual(object.boolCol, (dictionary["boolCol"] as! Bool))
  895. XCTAssertEqual(object.intCol, (dictionary["intCol"] as! Int))
  896. //XCTAssertEqual(object.floatCol, (dictionary["floatCol"] as! Float)) // FIXME: crashes with swift 3.2
  897. XCTAssertEqual(object.doubleCol, (dictionary["doubleCol"] as! Double))
  898. XCTAssertEqual(object.stringCol, (dictionary["stringCol"] as! String))
  899. XCTAssertEqual(object.binaryCol, (dictionary["binaryCol"] as! Data))
  900. XCTAssertEqual(object.dateCol, (dictionary["dateCol"] as! Date))
  901. XCTAssertEqual(object.objectCol!.boolCol, boolObjectValue)
  902. XCTAssertEqual(object.arrayCol.count, boolObjectListValues.count)
  903. for i in 0..<boolObjectListValues.count {
  904. XCTAssertEqual(object.arrayCol[i].boolCol, boolObjectListValues[i])
  905. }
  906. }
  907. private func verifySwiftOptionalObjectWithDictionaryLiteral(_ object: SwiftOptionalDefaultValuesObject,
  908. dictionary: [String: Any],
  909. boolObjectValue: Bool?) {
  910. XCTAssertEqual(object.optBoolCol.value, (dictionary["optBoolCol"] as! Bool?))
  911. XCTAssertEqual(object.optIntCol.value, (dictionary["optIntCol"] as! Int?))
  912. XCTAssertEqual(object.optInt8Col.value,
  913. ((dictionary["optInt8Col"] as! NSNumber?)?.int8Value).map({Int8($0)}))
  914. XCTAssertEqual(object.optInt16Col.value,
  915. ((dictionary["optInt16Col"] as! NSNumber?)?.int16Value).map({Int16($0)}))
  916. XCTAssertEqual(object.optInt32Col.value,
  917. ((dictionary["optInt32Col"] as! NSNumber?)?.int32Value).map({Int32($0)}))
  918. XCTAssertEqual(object.optInt64Col.value, (dictionary["optInt64Col"] as! NSNumber?)?.int64Value)
  919. XCTAssertEqual(object.optFloatCol.value, (dictionary["optFloatCol"] as! Float?))
  920. XCTAssertEqual(object.optDoubleCol.value, (dictionary["optDoubleCol"] as! Double?))
  921. XCTAssertEqual(object.optStringCol, (dictionary["optStringCol"] as! String?))
  922. XCTAssertEqual(object.optNSStringCol, (dictionary["optNSStringCol"] as! NSString))
  923. XCTAssertEqual(object.optBinaryCol, (dictionary["optBinaryCol"] as! Data?))
  924. XCTAssertEqual(object.optDateCol, (dictionary["optDateCol"] as! Date?))
  925. XCTAssertEqual(object.optObjectCol?.boolCol, boolObjectValue)
  926. }
  927. private func defaultSwiftObjectValuesWithReplacements(_ replace: [String: Any]) -> [String: Any] {
  928. var valueDict = SwiftObject.defaultValues()
  929. for (key, value) in replace {
  930. valueDict[key] = value
  931. }
  932. return valueDict
  933. }
  934. // return an array of valid values that can be used to initialize each type
  935. // swiftlint:disable:next cyclomatic_complexity
  936. private func validValuesForSwiftObjectType(_ type: PropertyType, _ array: Bool) -> [Any] {
  937. try! Realm().beginWrite()
  938. let persistedObject = try! Realm().create(SwiftBoolObject.self, value: [true])
  939. try! Realm().commitWrite()
  940. if array {
  941. return [
  942. [[true], [false]],
  943. [["boolCol": true], ["boolCol": false]],
  944. [SwiftBoolObject(value: [true]), SwiftBoolObject(value: [false])],
  945. [persistedObject, [false]]
  946. ]
  947. }
  948. switch type {
  949. case .bool: return [true, NSNumber(value: 0 as Int), NSNumber(value: 1 as Int)]
  950. case .int: return [NSNumber(value: 1 as Int)]
  951. case .float: return [NSNumber(value: 1 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  952. case .double: return [NSNumber(value: 1 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  953. case .string: return ["b"]
  954. case .data: return ["b".data(using: String.Encoding.utf8, allowLossyConversion: false)!]
  955. case .date: return [Date(timeIntervalSince1970: 2)]
  956. case .object: return [[true], ["boolCol": true], SwiftBoolObject(value: [true]), persistedObject]
  957. case .any: XCTFail("not supported")
  958. case .linkingObjects: XCTFail("not supported")
  959. }
  960. return []
  961. }
  962. // swiftlint:disable:next cyclomatic_complexity
  963. private func invalidValuesForSwiftObjectType(_ type: PropertyType, _ array: Bool) -> [Any] {
  964. try! Realm().beginWrite()
  965. let persistedObject = try! Realm().create(SwiftIntObject.self)
  966. try! Realm().commitWrite()
  967. if array {
  968. return ["invalid", [["a"]], [["boolCol": "a"]], [[SwiftIntObject()]], [[persistedObject]]]
  969. }
  970. switch type {
  971. case .bool: return ["invalid", NSNumber(value: 2 as Int), NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  972. case .int: return ["invalid", NSNumber(value: 1.1 as Float), NSNumber(value: 11.1 as Double)]
  973. case .float: return ["invalid", true, false]
  974. case .double: return ["invalid", true, false]
  975. case .string: return [0x197A71D, true, false]
  976. case .data: return ["invalid"]
  977. case .date: return ["invalid"]
  978. case .object: return ["invalid", ["a"], ["boolCol": "a"], SwiftIntObject()]
  979. case .any: XCTFail("not supported")
  980. case .linkingObjects: XCTFail("not supported")
  981. }
  982. return []
  983. }
  984. }