RealmTests.swift 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  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. #if DEBUG
  20. @testable import RealmSwift
  21. #else
  22. import RealmSwift
  23. #endif
  24. import Foundation
  25. class RealmTests: TestCase {
  26. enum TestError: Error {
  27. case intentional
  28. }
  29. func testFileURL() {
  30. XCTAssertEqual(try! Realm(fileURL: testRealmURL()).configuration.fileURL,
  31. testRealmURL())
  32. }
  33. func testReadOnly() {
  34. autoreleasepool {
  35. XCTAssertEqual(try! Realm().configuration.readOnly, false)
  36. try! Realm().write {
  37. try! Realm().create(SwiftIntObject.self, value: [100])
  38. }
  39. }
  40. let config = Realm.Configuration(fileURL: defaultRealmURL(), readOnly: true)
  41. let readOnlyRealm = try! Realm(configuration: config)
  42. XCTAssertEqual(true, readOnlyRealm.configuration.readOnly)
  43. XCTAssertEqual(1, readOnlyRealm.objects(SwiftIntObject.self).count)
  44. assertThrows(try! Realm(), "Realm has different readOnly settings")
  45. }
  46. func testOpeningInvalidPathThrows() {
  47. assertFails(.fileAccess) {
  48. try Realm(configuration: Realm.Configuration(fileURL: URL(fileURLWithPath: "/dev/null/foo")))
  49. }
  50. }
  51. func testReadOnlyFile() {
  52. autoreleasepool {
  53. let realm = try! Realm(fileURL: testRealmURL())
  54. try! realm.write {
  55. realm.create(SwiftStringObject.self, value: ["a"])
  56. }
  57. }
  58. let fileManager = FileManager.default
  59. try! fileManager.setAttributes([ FileAttributeKey.immutable: true ], ofItemAtPath: testRealmURL().path)
  60. // Should not be able to open read-write
  61. assertFails(.fileAccess) {
  62. try Realm(fileURL: testRealmURL())
  63. }
  64. assertSucceeds {
  65. let realm = try Realm(configuration:
  66. Realm.Configuration(fileURL: testRealmURL(), readOnly: true))
  67. XCTAssertEqual(1, realm.objects(SwiftStringObject.self).count)
  68. }
  69. try! fileManager.setAttributes([ FileAttributeKey.immutable: false ], ofItemAtPath: testRealmURL().path)
  70. }
  71. func testReadOnlyRealmMustExist() {
  72. assertFails(.fileNotFound) {
  73. try Realm(configuration:
  74. Realm.Configuration(fileURL: defaultRealmURL(), readOnly: true))
  75. }
  76. }
  77. func testFilePermissionDenied() {
  78. autoreleasepool {
  79. _ = try! Realm(fileURL: testRealmURL())
  80. }
  81. // Make Realm at test path temporarily unreadable
  82. let fileManager = FileManager.default
  83. let permissions = try! fileManager
  84. .attributesOfItem(atPath: testRealmURL().path)[FileAttributeKey.posixPermissions] as! NSNumber
  85. try! fileManager.setAttributes([ FileAttributeKey.posixPermissions: 0000 ],
  86. ofItemAtPath: testRealmURL().path)
  87. assertFails(.filePermissionDenied) {
  88. try Realm(fileURL: testRealmURL())
  89. }
  90. try! fileManager.setAttributes([FileAttributeKey.posixPermissions: permissions], ofItemAtPath: testRealmURL().path)
  91. }
  92. #if !SWIFT_PACKAGE && DEBUG
  93. func testFileFormatUpgradeRequiredButDisabled() {
  94. var config = Realm.Configuration()
  95. let bundledRealmPath = Bundle(for: RealmTests.self).path(forResource: "fileformat-pre-null.realm",
  96. ofType: nil)!
  97. try! FileManager.default.copyItem(atPath: bundledRealmPath, toPath: config.fileURL!.path)
  98. config.disableFormatUpgrade = true
  99. assertFails(Realm.Error.fileFormatUpgradeRequired) {
  100. try Realm(configuration: config)
  101. }
  102. }
  103. #endif
  104. func testSchema() {
  105. let schema = try! Realm().schema
  106. XCTAssert(schema as AnyObject is Schema)
  107. XCTAssertEqual(1, schema.objectSchema.filter({ $0.className == "SwiftStringObject" }).count)
  108. }
  109. func testIsEmpty() {
  110. let realm = try! Realm()
  111. XCTAssert(realm.isEmpty, "Realm should be empty on creation.")
  112. realm.beginWrite()
  113. realm.create(SwiftStringObject.self, value: ["a"])
  114. XCTAssertFalse(realm.isEmpty, "Realm should not be empty within a write transaction after adding an object.")
  115. realm.cancelWrite()
  116. XCTAssertTrue(realm.isEmpty, "Realm should be empty after canceling a write transaction that added an object.")
  117. realm.beginWrite()
  118. realm.create(SwiftStringObject.self, value: ["a"])
  119. try! realm.commitWrite()
  120. XCTAssertFalse(realm.isEmpty,
  121. "Realm should not be empty after committing a write transaction that added an object.")
  122. }
  123. func testInit() {
  124. XCTAssertEqual(try! Realm(fileURL: testRealmURL()).configuration.fileURL,
  125. testRealmURL())
  126. }
  127. func testInitFailable() {
  128. autoreleasepool {
  129. _ = try! Realm()
  130. }
  131. FileManager.default.createFile(atPath: defaultRealmURL().path,
  132. contents: "a".data(using: String.Encoding.utf8, allowLossyConversion: false),
  133. attributes: nil)
  134. assertFails(.fileAccess) {
  135. _ = try Realm()
  136. XCTFail("Realm creation should have failed")
  137. }
  138. }
  139. func testInitInMemory() {
  140. autoreleasepool {
  141. let realm = inMemoryRealm("identifier")
  142. try! realm.write {
  143. realm.create(SwiftIntObject.self, value: [1])
  144. return
  145. }
  146. }
  147. let realm = inMemoryRealm("identifier")
  148. XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 0)
  149. try! realm.write {
  150. realm.create(SwiftIntObject.self, value: [1])
  151. XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 1)
  152. inMemoryRealm("identifier").create(SwiftIntObject.self, value: [1])
  153. XCTAssertEqual(realm.objects(SwiftIntObject.self).count, 2)
  154. }
  155. let realm2 = inMemoryRealm("identifier2")
  156. XCTAssertEqual(realm2.objects(SwiftIntObject.self).count, 0)
  157. }
  158. func testInitCustomClassList() {
  159. let configuration = Realm.Configuration(fileURL: Realm.Configuration.defaultConfiguration.fileURL,
  160. objectTypes: [SwiftStringObject.self])
  161. XCTAssert(configuration.objectTypes! is [SwiftStringObject.Type])
  162. let realm = try! Realm(configuration: configuration)
  163. XCTAssertEqual(["SwiftStringObject"], realm.schema.objectSchema.map { $0.className })
  164. }
  165. func testWrite() {
  166. try! Realm().write {
  167. self.assertThrows(try! Realm().beginWrite())
  168. self.assertThrows(try! Realm().write { })
  169. try! Realm().create(SwiftStringObject.self, value: ["1"])
  170. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  171. }
  172. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  173. }
  174. func testDynamicWrite() {
  175. try! Realm().write {
  176. self.assertThrows(try! Realm().beginWrite())
  177. self.assertThrows(try! Realm().write { })
  178. try! Realm().dynamicCreate("SwiftStringObject", value: ["1"])
  179. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  180. }
  181. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  182. }
  183. func testWriteWithoutNotifying() {
  184. let realm = try! Realm()
  185. let token = realm.observe { _, _ in
  186. XCTFail("should not have been called")
  187. }
  188. try! realm.write(withoutNotifying: [token]) {
  189. realm.deleteAll()
  190. }
  191. // local realm notifications are called synchronously so no need to wait for anything
  192. token.invalidate()
  193. }
  194. func testDynamicWriteSubscripting() {
  195. try! Realm().beginWrite()
  196. let object = try! Realm().dynamicCreate("SwiftStringObject", value: ["1"])
  197. try! Realm().commitWrite()
  198. XCTAssertNotNil(object, "Dynamic Object Creation Failed")
  199. let stringVal = object["stringCol"] as! String
  200. XCTAssertEqual(stringVal, "1", "Object Subscripting Failed")
  201. }
  202. func testBeginWrite() {
  203. try! Realm().beginWrite()
  204. assertThrows(try! Realm().beginWrite())
  205. try! Realm().cancelWrite()
  206. try! Realm().beginWrite()
  207. try! Realm().create(SwiftStringObject.self, value: ["1"])
  208. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  209. }
  210. func testWriteReturning() {
  211. let realm = try! Realm()
  212. let object = try! realm.write {
  213. return realm.create(SwiftStringObject.self, value: ["1"])
  214. }
  215. XCTAssertEqual(object.stringCol, "1")
  216. }
  217. func testCommitWrite() {
  218. try! Realm().beginWrite()
  219. try! Realm().create(SwiftStringObject.self, value: ["1"])
  220. try! Realm().commitWrite()
  221. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 1)
  222. try! Realm().beginWrite()
  223. }
  224. func testCancelWrite() {
  225. assertThrows(try! Realm().cancelWrite())
  226. try! Realm().beginWrite()
  227. try! Realm().create(SwiftStringObject.self, value: ["1"])
  228. try! Realm().cancelWrite()
  229. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0)
  230. try! Realm().write {
  231. self.assertThrows(self.realmWithTestPath().cancelWrite())
  232. let object = try! Realm().create(SwiftStringObject.self)
  233. try! Realm().cancelWrite()
  234. XCTAssertTrue(object.isInvalidated)
  235. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0)
  236. }
  237. XCTAssertEqual(try! Realm().objects(SwiftStringObject.self).count, 0)
  238. }
  239. func testThrowsWrite() {
  240. assertFails(TestError.intentional) {
  241. try Realm().write {
  242. throw TestError.intentional
  243. }
  244. }
  245. assertFails(TestError.intentional) {
  246. try Realm().write {
  247. try! Realm().create(SwiftStringObject.self, value: ["1"])
  248. throw TestError.intentional
  249. }
  250. }
  251. }
  252. func testInWriteTransaction() {
  253. let realm = try! Realm()
  254. XCTAssertFalse(realm.isInWriteTransaction)
  255. realm.beginWrite()
  256. XCTAssertTrue(realm.isInWriteTransaction)
  257. realm.cancelWrite()
  258. try! realm.write {
  259. XCTAssertTrue(realm.isInWriteTransaction)
  260. realm.cancelWrite()
  261. XCTAssertFalse(realm.isInWriteTransaction)
  262. }
  263. realm.beginWrite()
  264. realm.invalidate()
  265. XCTAssertFalse(realm.isInWriteTransaction)
  266. }
  267. func testAddSingleObject() {
  268. let realm = try! Realm()
  269. assertThrows(_ = realm.add(SwiftObject()))
  270. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  271. var defaultRealmObject: SwiftObject!
  272. try! realm.write {
  273. defaultRealmObject = SwiftObject()
  274. realm.add(defaultRealmObject)
  275. XCTAssertEqual(1, realm.objects(SwiftObject.self).count)
  276. realm.add(defaultRealmObject)
  277. XCTAssertEqual(1, realm.objects(SwiftObject.self).count)
  278. }
  279. XCTAssertEqual(1, realm.objects(SwiftObject.self).count)
  280. let testRealm = realmWithTestPath()
  281. try! testRealm.write {
  282. self.assertThrows(_ = testRealm.add(defaultRealmObject))
  283. }
  284. }
  285. func testAddWithUpdateSingleObject() {
  286. let realm = try! Realm()
  287. XCTAssertEqual(0, realm.objects(SwiftPrimaryStringObject.self).count)
  288. var defaultRealmObject: SwiftPrimaryStringObject!
  289. try! realm.write {
  290. defaultRealmObject = SwiftPrimaryStringObject()
  291. realm.add(defaultRealmObject, update: .all)
  292. XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
  293. realm.add(SwiftPrimaryStringObject(), update: .all)
  294. XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
  295. }
  296. XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
  297. let testRealm = realmWithTestPath()
  298. try! testRealm.write {
  299. self.assertThrows(_ = testRealm.add(defaultRealmObject, update: .all))
  300. }
  301. }
  302. func testAddMultipleObjects() {
  303. let realm = try! Realm()
  304. assertThrows(_ = realm.add([SwiftObject(), SwiftObject()]))
  305. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  306. try! realm.write {
  307. let objs = [SwiftObject(), SwiftObject()]
  308. realm.add(objs)
  309. XCTAssertEqual(2, realm.objects(SwiftObject.self).count)
  310. }
  311. XCTAssertEqual(2, realm.objects(SwiftObject.self).count)
  312. let testRealm = realmWithTestPath()
  313. try! testRealm.write {
  314. self.assertThrows(_ = testRealm.add(realm.objects(SwiftObject.self)))
  315. }
  316. }
  317. func testAddWithUpdateMultipleObjects() {
  318. let realm = try! Realm()
  319. XCTAssertEqual(0, realm.objects(SwiftPrimaryStringObject.self).count)
  320. try! realm.write {
  321. let objs = [SwiftPrimaryStringObject(), SwiftPrimaryStringObject()]
  322. realm.add(objs, update: .all)
  323. XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
  324. }
  325. XCTAssertEqual(1, realm.objects(SwiftPrimaryStringObject.self).count)
  326. let testRealm = realmWithTestPath()
  327. try! testRealm.write {
  328. self.assertThrows(_ = testRealm.add(realm.objects(SwiftPrimaryStringObject.self), update: .all))
  329. }
  330. }
  331. // create() tests are in ObjectCreationTests.swift
  332. func testDeleteSingleObject() {
  333. let realm = try! Realm()
  334. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  335. assertThrows(_ = realm.delete(SwiftObject()))
  336. var defaultRealmObject: SwiftObject!
  337. try! realm.write {
  338. defaultRealmObject = SwiftObject()
  339. self.assertThrows(_ = realm.delete(defaultRealmObject))
  340. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  341. realm.add(defaultRealmObject)
  342. XCTAssertEqual(1, realm.objects(SwiftObject.self).count)
  343. realm.delete(defaultRealmObject)
  344. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  345. }
  346. assertThrows(_ = realm.delete(defaultRealmObject))
  347. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  348. let testRealm = realmWithTestPath()
  349. assertThrows(_ = testRealm.delete(defaultRealmObject))
  350. try! testRealm.write {
  351. self.assertThrows(_ = testRealm.delete(defaultRealmObject))
  352. }
  353. }
  354. func testDeleteSequenceOfObjects() {
  355. let realm = try! Realm()
  356. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  357. var objs: [SwiftObject]!
  358. try! realm.write {
  359. objs = [SwiftObject(), SwiftObject()]
  360. realm.add(objs)
  361. XCTAssertEqual(2, realm.objects(SwiftObject.self).count)
  362. realm.delete(objs)
  363. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  364. }
  365. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  366. let testRealm = realmWithTestPath()
  367. assertThrows(_ = testRealm.delete(objs))
  368. try! testRealm.write {
  369. self.assertThrows(_ = testRealm.delete(objs))
  370. }
  371. }
  372. func testDeleteListOfObjects() {
  373. let realm = try! Realm()
  374. XCTAssertEqual(0, realm.objects(SwiftCompanyObject.self).count)
  375. try! realm.write {
  376. let obj = SwiftCompanyObject()
  377. obj.employees.append(SwiftEmployeeObject())
  378. realm.add(obj)
  379. XCTAssertEqual(1, realm.objects(SwiftEmployeeObject.self).count)
  380. realm.delete(obj.employees)
  381. XCTAssertEqual(0, obj.employees.count)
  382. XCTAssertEqual(0, realm.objects(SwiftEmployeeObject.self).count)
  383. }
  384. XCTAssertEqual(0, realm.objects(SwiftEmployeeObject.self).count)
  385. }
  386. func testDeleteResults() {
  387. let realm = try! Realm(fileURL: testRealmURL())
  388. XCTAssertEqual(0, realm.objects(SwiftCompanyObject.self).count)
  389. try! realm.write {
  390. realm.add(SwiftIntObject(value: [1]))
  391. realm.add(SwiftIntObject(value: [1]))
  392. realm.add(SwiftIntObject(value: [2]))
  393. XCTAssertEqual(3, realm.objects(SwiftIntObject.self).count)
  394. realm.delete(realm.objects(SwiftIntObject.self).filter("intCol = 1"))
  395. XCTAssertEqual(1, realm.objects(SwiftIntObject.self).count)
  396. }
  397. XCTAssertEqual(1, realm.objects(SwiftIntObject.self).count)
  398. }
  399. func testDeleteAll() {
  400. let realm = try! Realm()
  401. try! realm.write {
  402. realm.add(SwiftObject())
  403. XCTAssertEqual(1, realm.objects(SwiftObject.self).count)
  404. realm.deleteAll()
  405. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  406. }
  407. XCTAssertEqual(0, realm.objects(SwiftObject.self).count)
  408. }
  409. func testObjects() {
  410. try! Realm().write {
  411. try! Realm().create(SwiftIntObject.self, value: [100])
  412. try! Realm().create(SwiftIntObject.self, value: [200])
  413. try! Realm().create(SwiftIntObject.self, value: [300])
  414. }
  415. XCTAssertEqual(0, try! Realm().objects(SwiftStringObject.self).count)
  416. XCTAssertEqual(3, try! Realm().objects(SwiftIntObject.self).count)
  417. assertThrows(try! Realm().objects(Object.self))
  418. }
  419. func testDynamicObjects() {
  420. try! Realm().write {
  421. try! Realm().create(SwiftIntObject.self, value: [100])
  422. try! Realm().create(SwiftIntObject.self, value: [200])
  423. try! Realm().create(SwiftIntObject.self, value: [300])
  424. }
  425. XCTAssertEqual(0, try! Realm().dynamicObjects("SwiftStringObject").count)
  426. XCTAssertEqual(3, try! Realm().dynamicObjects("SwiftIntObject").count)
  427. assertThrows(try! Realm().dynamicObjects("Object"))
  428. }
  429. func testDynamicObjectProperties() {
  430. try! Realm().write {
  431. try! Realm().create(SwiftObject.self)
  432. }
  433. let object = try! Realm().dynamicObjects("SwiftObject")[0]
  434. let dictionary = SwiftObject.defaultValues()
  435. XCTAssertEqual(object["boolCol"] as? NSNumber, dictionary["boolCol"] as! NSNumber?)
  436. XCTAssertEqual(object["intCol"] as? NSNumber, dictionary["intCol"] as! NSNumber?)
  437. XCTAssertEqual(object["floatCol"] as! Float, dictionary["floatCol"] as! Float, accuracy: 0.001)
  438. XCTAssertEqual(object["doubleCol"] as? NSNumber, dictionary["doubleCol"] as! NSNumber?)
  439. XCTAssertEqual(object["stringCol"] as! String?, dictionary["stringCol"] as! String?)
  440. XCTAssertEqual(object["binaryCol"] as! NSData?, dictionary["binaryCol"] as! NSData?)
  441. XCTAssertEqual(object["dateCol"] as! Date?, dictionary["dateCol"] as! Date?)
  442. XCTAssertEqual((object["objectCol"] as? SwiftBoolObject)?.boolCol, false)
  443. }
  444. func testDynamicObjectOptionalProperties() {
  445. try! Realm().write {
  446. try! Realm().create(SwiftOptionalDefaultValuesObject.self)
  447. }
  448. let object = try! Realm().dynamicObjects("SwiftOptionalDefaultValuesObject")[0]
  449. let dictionary = SwiftOptionalDefaultValuesObject.defaultValues()
  450. XCTAssertEqual(object["optIntCol"] as? NSNumber, dictionary["optIntCol"] as! NSNumber?)
  451. XCTAssertEqual(object["optInt8Col"] as? NSNumber, dictionary["optInt8Col"] as! NSNumber?)
  452. XCTAssertEqual(object["optInt16Col"] as? NSNumber, dictionary["optInt16Col"] as! NSNumber?)
  453. XCTAssertEqual(object["optInt32Col"] as? NSNumber, dictionary["optInt32Col"] as! NSNumber?)
  454. XCTAssertEqual(object["optInt64Col"] as? NSNumber, dictionary["optInt64Col"] as! NSNumber?)
  455. XCTAssertEqual(object["optFloatCol"] as? NSNumber, dictionary["optFloatCol"] as! NSNumber?)
  456. XCTAssertEqual(object["optDoubleCol"] as? NSNumber, dictionary["optDoubleCol"] as! NSNumber?)
  457. XCTAssertEqual(object["optStringCol"] as! String?, dictionary["optStringCol"] as! String?)
  458. XCTAssertEqual(object["optNSStringCol"] as! String?, dictionary["optNSStringCol"] as! String?)
  459. XCTAssertEqual(object["optBinaryCol"] as! NSData?, dictionary["optBinaryCol"] as! NSData?)
  460. XCTAssertEqual(object["optDateCol"] as! Date?, dictionary["optDateCol"] as! Date?)
  461. XCTAssertEqual((object["optObjectCol"] as? SwiftBoolObject)?.boolCol, true)
  462. }
  463. func testIterateDynamicObjects() {
  464. try! Realm().write {
  465. for _ in 1..<3 {
  466. try! Realm().create(SwiftObject.self)
  467. }
  468. }
  469. let objects = try! Realm().dynamicObjects("SwiftObject")
  470. let dictionary = SwiftObject.defaultValues()
  471. for object in objects {
  472. XCTAssertEqual(object["boolCol"] as? NSNumber, dictionary["boolCol"] as! NSNumber?)
  473. XCTAssertEqual(object["intCol"] as? NSNumber, dictionary["intCol"] as! NSNumber?)
  474. XCTAssertEqual(object["floatCol"] as? NSNumber, dictionary["floatCol"] as! NSNumber?)
  475. XCTAssertEqual(object["doubleCol"] as? NSNumber, dictionary["doubleCol"] as! NSNumber?)
  476. XCTAssertEqual(object["stringCol"] as! String?, dictionary["stringCol"] as! String?)
  477. XCTAssertEqual(object["binaryCol"] as! NSData?, dictionary["binaryCol"] as! NSData?)
  478. XCTAssertEqual(object["dateCol"] as! Date?, dictionary["dateCol"] as! Date?)
  479. XCTAssertEqual((object["objectCol"] as? SwiftBoolObject)?.boolCol, false)
  480. }
  481. }
  482. func testDynamicObjectListProperties() {
  483. try! Realm().write {
  484. try! Realm().create(SwiftArrayPropertyObject.self, value: ["string", [["array"]], [[2]]])
  485. }
  486. let object = try! Realm().dynamicObjects("SwiftArrayPropertyObject")[0]
  487. XCTAssertEqual(object["name"] as? String, "string")
  488. let array = object["array"] as! List<DynamicObject>
  489. XCTAssertEqual(array.first!["stringCol"] as? String, "array")
  490. XCTAssertEqual(array.last!["stringCol"] as? String, "array")
  491. for object in array {
  492. XCTAssertEqual(object["stringCol"] as? String, "array")
  493. }
  494. let intArray = object["intArray"] as! List<DynamicObject>
  495. XCTAssertEqual(intArray[0]["intCol"] as? Int, 2)
  496. XCTAssertEqual(intArray.first!["intCol"] as? Int, 2)
  497. XCTAssertEqual(intArray.last!["intCol"] as? Int, 2)
  498. for object in intArray {
  499. XCTAssertEqual(object["intCol"] as? Int, 2)
  500. }
  501. }
  502. func testIntPrimaryKey() {
  503. func testIntPrimaryKey<O: Object>(for type: O.Type)
  504. where O: SwiftPrimaryKeyObjectType, O.PrimaryKey: ExpressibleByIntegerLiteral {
  505. let realm = try! Realm()
  506. try! realm.write {
  507. realm.create(type, value: ["a", 1])
  508. realm.create(type, value: ["b", 2])
  509. }
  510. let object = realm.object(ofType: type, forPrimaryKey: 1 as O.PrimaryKey)
  511. XCTAssertNotNil(object)
  512. let missingObject = realm.object(ofType: type, forPrimaryKey: 0 as O.PrimaryKey)
  513. XCTAssertNil(missingObject)
  514. }
  515. testIntPrimaryKey(for: SwiftPrimaryIntObject.self)
  516. testIntPrimaryKey(for: SwiftPrimaryInt8Object.self)
  517. testIntPrimaryKey(for: SwiftPrimaryInt16Object.self)
  518. testIntPrimaryKey(for: SwiftPrimaryInt32Object.self)
  519. testIntPrimaryKey(for: SwiftPrimaryInt64Object.self)
  520. }
  521. func testOptionalIntPrimaryKey() {
  522. func testOptionalIntPrimaryKey<O: Object, Wrapped>(for type: O.Type, _ wrapped: Wrapped.Type)
  523. where Wrapped: ExpressibleByIntegerLiteral {
  524. let realm = try! Realm()
  525. try! realm.write {
  526. realm.create(type, value: ["a", NSNull()])
  527. realm.create(type, value: ["b", 2])
  528. }
  529. let object1a = realm.object(ofType: type, forPrimaryKey: NSNull())
  530. XCTAssertNotNil(object1a)
  531. let object1b = realm.object(ofType: type, forPrimaryKey: nil as Wrapped?)
  532. XCTAssertNotNil(object1b)
  533. let object2 = realm.object(ofType: type, forPrimaryKey: 2 as Wrapped)
  534. XCTAssertNotNil(object2)
  535. let missingObject = realm.object(ofType: type, forPrimaryKey: 0 as Wrapped)
  536. XCTAssertNil(missingObject)
  537. }
  538. testOptionalIntPrimaryKey(for: SwiftPrimaryOptionalIntObject.self, Int.self)
  539. testOptionalIntPrimaryKey(for: SwiftPrimaryOptionalInt8Object.self, Int8.self)
  540. testOptionalIntPrimaryKey(for: SwiftPrimaryOptionalInt16Object.self, Int16.self)
  541. testOptionalIntPrimaryKey(for: SwiftPrimaryOptionalInt32Object.self, Int32.self)
  542. testOptionalIntPrimaryKey(for: SwiftPrimaryOptionalInt64Object.self, Int64.self)
  543. }
  544. func testStringPrimaryKey() {
  545. let realm = try! Realm()
  546. try! realm.write {
  547. realm.create(SwiftPrimaryStringObject.self, value: ["a", 1])
  548. realm.create(SwiftPrimaryStringObject.self, value: ["b", 2])
  549. }
  550. // When this is directly inside the XCTAssertNotNil, it doesn't work
  551. let object = realm.object(ofType: SwiftPrimaryStringObject.self, forPrimaryKey: "a")
  552. XCTAssertNotNil(object)
  553. // When this is directly inside the XCTAssertNil, it fails for some reason
  554. let missingObject = realm.object(ofType: SwiftPrimaryStringObject.self, forPrimaryKey: "z")
  555. XCTAssertNil(missingObject)
  556. }
  557. func testOptionalStringPrimaryKey() {
  558. let realm = try! Realm()
  559. try! realm.write {
  560. realm.create(SwiftPrimaryStringObject.self, value: ["a", 1])
  561. realm.create(SwiftPrimaryStringObject.self, value: ["b", 2])
  562. realm.create(SwiftPrimaryOptionalStringObject.self, value: [NSNull(), 1])
  563. realm.create(SwiftPrimaryOptionalStringObject.self, value: ["b", 2])
  564. }
  565. let object1 = realm.object(ofType: SwiftPrimaryOptionalStringObject.self, forPrimaryKey: NSNull())
  566. XCTAssertNotNil(object1)
  567. let object2 = realm.object(ofType: SwiftPrimaryOptionalStringObject.self, forPrimaryKey: "b")
  568. XCTAssertNotNil(object2)
  569. let missingObject = realm.object(ofType: SwiftPrimaryOptionalStringObject.self, forPrimaryKey: "z")
  570. XCTAssertNil(missingObject)
  571. }
  572. func testDynamicObjectForPrimaryKey() {
  573. let realm = try! Realm()
  574. try! realm.write {
  575. realm.create(SwiftPrimaryStringObject.self, value: ["a", 1])
  576. realm.create(SwiftPrimaryStringObject.self, value: ["b", 2])
  577. }
  578. XCTAssertNotNil(realm.dynamicObject(ofType: "SwiftPrimaryStringObject", forPrimaryKey: "a"))
  579. XCTAssertNil(realm.dynamicObject(ofType: "SwiftPrimaryStringObject", forPrimaryKey: "z"))
  580. }
  581. func testDynamicObjectForPrimaryKeySubscripting() {
  582. let realm = try! Realm()
  583. try! realm.write {
  584. realm.create(SwiftPrimaryStringObject.self, value: ["a", 1])
  585. }
  586. let object = realm.dynamicObject(ofType: "SwiftPrimaryStringObject", forPrimaryKey: "a")
  587. let stringVal = object!["stringCol"] as! String
  588. XCTAssertEqual(stringVal, "a", "Object Subscripting Failed!")
  589. }
  590. func testObserve() {
  591. let realm = try! Realm()
  592. var notificationCalled = false
  593. let token = realm.observe { _, realm in
  594. XCTAssertEqual(realm.configuration.fileURL, self.defaultRealmURL())
  595. notificationCalled = true
  596. }
  597. XCTAssertFalse(notificationCalled)
  598. try! realm.write {}
  599. XCTAssertTrue(notificationCalled)
  600. token.invalidate()
  601. }
  602. func testRemoveNotification() {
  603. let realm = try! Realm()
  604. var notificationCalled = false
  605. let token = realm.observe { (_, realm) -> Void in
  606. XCTAssertEqual(realm.configuration.fileURL, self.defaultRealmURL())
  607. notificationCalled = true
  608. }
  609. token.invalidate()
  610. try! realm.write {}
  611. XCTAssertFalse(notificationCalled)
  612. }
  613. func testAutorefresh() {
  614. let realm = try! Realm()
  615. XCTAssertTrue(realm.autorefresh, "Autorefresh should default to true")
  616. realm.autorefresh = false
  617. XCTAssertFalse(realm.autorefresh)
  618. realm.autorefresh = true
  619. XCTAssertTrue(realm.autorefresh)
  620. // test that autoreresh is applied
  621. // we have two notifications, one for opening the realm, and a second when performing our transaction
  622. let notificationFired = expectation(description: "notification fired")
  623. let token = realm.observe { _, realm in
  624. XCTAssertNotNil(realm, "Realm should not be nil")
  625. notificationFired.fulfill()
  626. }
  627. dispatchSyncNewThread {
  628. let realm = try! Realm()
  629. try! realm.write {
  630. realm.create(SwiftStringObject.self, value: ["string"])
  631. }
  632. }
  633. waitForExpectations(timeout: 1, handler: nil)
  634. token.invalidate()
  635. // get object
  636. let results = realm.objects(SwiftStringObject.self)
  637. XCTAssertEqual(results.count, Int(1), "There should be 1 object of type StringObject")
  638. XCTAssertEqual(results[0].stringCol, "string", "Value of first column should be 'string'")
  639. }
  640. func testRefresh() {
  641. let realm = try! Realm()
  642. realm.autorefresh = false
  643. // test that autoreresh is not applied
  644. // we have two notifications, one for opening the realm, and a second when performing our transaction
  645. let notificationFired = expectation(description: "notification fired")
  646. let token = realm.observe { _, realm in
  647. XCTAssertNotNil(realm, "Realm should not be nil")
  648. notificationFired.fulfill()
  649. }
  650. let results = realm.objects(SwiftStringObject.self)
  651. XCTAssertEqual(results.count, Int(0), "There should be 1 object of type StringObject")
  652. dispatchSyncNewThread {
  653. try! Realm().write {
  654. try! Realm().create(SwiftStringObject.self, value: ["string"])
  655. return
  656. }
  657. }
  658. waitForExpectations(timeout: 1, handler: nil)
  659. token.invalidate()
  660. XCTAssertEqual(results.count, Int(0), "There should be 1 object of type StringObject")
  661. // refresh
  662. realm.refresh()
  663. XCTAssertEqual(results.count, Int(1), "There should be 1 object of type StringObject")
  664. XCTAssertEqual(results[0].stringCol, "string", "Value of first column should be 'string'")
  665. }
  666. func testInvalidate() {
  667. let realm = try! Realm()
  668. let object = SwiftObject()
  669. try! realm.write {
  670. realm.add(object)
  671. return
  672. }
  673. realm.invalidate()
  674. XCTAssertEqual(object.isInvalidated, true)
  675. try! realm.write {
  676. realm.add(SwiftObject())
  677. return
  678. }
  679. XCTAssertEqual(realm.objects(SwiftObject.self).count, 2)
  680. XCTAssertEqual(object.isInvalidated, true)
  681. }
  682. func testWriteCopyToPath() {
  683. let realm = try! Realm()
  684. try! realm.write {
  685. realm.add(SwiftObject())
  686. }
  687. let fileURL = defaultRealmURL().deletingLastPathComponent().appendingPathComponent("copy.realm")
  688. do {
  689. try realm.writeCopy(toFile: fileURL)
  690. } catch {
  691. XCTFail("writeCopyToURL failed")
  692. }
  693. autoreleasepool {
  694. let copy = try! Realm(fileURL: fileURL)
  695. XCTAssertEqual(1, copy.objects(SwiftObject.self).count)
  696. }
  697. try! FileManager.default.removeItem(at: fileURL)
  698. }
  699. func testEquals() {
  700. let realm = try! Realm()
  701. XCTAssertTrue(try! realm == Realm())
  702. let testRealm = realmWithTestPath()
  703. XCTAssertFalse(realm == testRealm)
  704. dispatchSyncNewThread {
  705. let otherThreadRealm = try! Realm()
  706. XCTAssertFalse(realm == otherThreadRealm)
  707. }
  708. }
  709. func testCatchSpecificErrors() {
  710. do {
  711. _ = try Realm(configuration: Realm.Configuration(fileURL: URL(fileURLWithPath: "/dev/null/foo")))
  712. XCTFail("Error should be thrown")
  713. } catch Realm.Error.fileAccess {
  714. // Success to catch the error
  715. } catch {
  716. XCTFail("Failed to brigde RLMError to Realm.Error")
  717. }
  718. do {
  719. _ = try Realm(configuration: Realm.Configuration(fileURL: defaultRealmURL(), readOnly: true))
  720. XCTFail("Error should be thrown")
  721. } catch Realm.Error.fileNotFound {
  722. // Success to catch the error
  723. } catch {
  724. XCTFail("Failed to brigde RLMError to Realm.Error")
  725. }
  726. }
  727. func testExists() {
  728. let config = Realm.Configuration()
  729. XCTAssertFalse(Realm.fileExists(for: config))
  730. autoreleasepool { _ = try! Realm(configuration: config) }
  731. XCTAssertTrue(Realm.fileExists(for: config))
  732. XCTAssertTrue(try! Realm.deleteFiles(for: config))
  733. XCTAssertFalse(Realm.fileExists(for: config))
  734. }
  735. }