SwiftRealmTests.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2014 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 Realm
  20. import RealmTestSupport
  21. class SwiftRLMRealmTests: RLMTestCase {
  22. // No models
  23. func testRealmExists() {
  24. let realm = realmWithTestPath()
  25. XCTAssertNotNil(realm, "realm should not be nil");
  26. XCTAssertTrue((realm as AnyObject) is RLMRealm, "realm should be of class RLMRealm")
  27. }
  28. func testEmptyWriteTransaction() {
  29. let realm = realmWithTestPath()
  30. realm.beginWriteTransaction()
  31. try! realm.commitWriteTransaction()
  32. }
  33. // Swift models
  34. func testRealmAddAndRemoveObjects() {
  35. let realm = realmWithTestPath()
  36. realm.beginWriteTransaction()
  37. _ = SwiftRLMStringObject.create(in: realm, withValue: ["a"])
  38. _ = SwiftRLMStringObject.create(in: realm, withValue: ["b"])
  39. _ = SwiftRLMStringObject.create(in: realm, withValue: ["c"])
  40. XCTAssertEqual(SwiftRLMStringObject.allObjects(in: realm).count, UInt(3), "Expecting 3 objects")
  41. try! realm.commitWriteTransaction()
  42. // test again after write transaction
  43. var objects = SwiftRLMStringObject.allObjects(in: realm)
  44. XCTAssertEqual(objects.count, UInt(3), "Expecting 3 objects")
  45. XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "a", "Expecting column to be 'a'")
  46. realm.beginWriteTransaction()
  47. realm.delete(objects[2] as! SwiftRLMStringObject)
  48. realm.delete(objects[0] as! SwiftRLMStringObject)
  49. XCTAssertEqual(SwiftRLMStringObject.allObjects(in: realm).count, UInt(1), "Expecting 1 object")
  50. try! realm.commitWriteTransaction()
  51. objects = SwiftRLMStringObject.allObjects(in: realm)
  52. XCTAssertEqual(objects.count, UInt(1), "Expecting 1 object")
  53. XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "b", "Expecting column to be 'b'")
  54. }
  55. func testRealmIsUpdatedAfterBackgroundUpdate() {
  56. let realm = realmWithTestPath()
  57. // we have two notifications, one for opening the realm, and a second when performing our transaction
  58. let notificationFired = expectation(description: "notification fired")
  59. let token = realm.addNotificationBlock { note, realm in
  60. XCTAssertNotNil(realm, "Realm should not be nil")
  61. notificationFired.fulfill()
  62. }
  63. dispatchAsync {
  64. let realm = self.realmWithTestPath()
  65. realm.beginWriteTransaction()
  66. _ = SwiftRLMStringObject.create(in: realm, withValue: ["string"])
  67. try! realm.commitWriteTransaction()
  68. }
  69. waitForExpectations(timeout: 2.0, handler: nil)
  70. token.invalidate()
  71. // get object
  72. let objects = SwiftRLMStringObject.allObjects(in: realm)
  73. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
  74. XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
  75. }
  76. func testRealmIgnoresProperties() {
  77. let realm = realmWithTestPath()
  78. let object = SwiftRLMIgnoredPropertiesObject()
  79. realm.beginWriteTransaction()
  80. object.name = "@fz"
  81. object.age = 31
  82. realm.add(object)
  83. try! realm.commitWriteTransaction()
  84. // This shouldn't do anything.
  85. realm.beginWriteTransaction()
  86. object.runtimeProperty = NSObject()
  87. try! realm.commitWriteTransaction()
  88. let objects = SwiftRLMIgnoredPropertiesObject.allObjects(in: realm)
  89. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type SwiftRLMIgnoredPropertiesObject")
  90. let retrievedObject = objects[0] as! SwiftRLMIgnoredPropertiesObject
  91. XCTAssertNil(retrievedObject.runtimeProperty, "Ignored property should be nil")
  92. XCTAssertEqual(retrievedObject.name, "@fz", "Value of the name column doesn't match the assigned one.")
  93. XCTAssertEqual(retrievedObject.objectSchema.properties.count, 2, "Only 'name' and 'age' properties should be detected by Realm")
  94. }
  95. func testUpdatingSortedArrayAfterBackgroundUpdate() {
  96. let realm = realmWithTestPath()
  97. let objs = SwiftRLMIntObject.allObjects(in: realm)
  98. let objects = SwiftRLMIntObject.allObjects(in: realm).sortedResults(usingKeyPath: "intCol", ascending: true)
  99. let updateComplete = expectation(description: "background update complete")
  100. let token = realm.addNotificationBlock() { (_, _) in
  101. XCTAssertEqual(objs.count, UInt(2))
  102. XCTAssertEqual(objs.sortedResults(usingKeyPath: "intCol", ascending: true).count, UInt(2))
  103. XCTAssertEqual(objects.count, UInt(2))
  104. updateComplete.fulfill()
  105. }
  106. dispatchAsync {
  107. let realm = self.realmWithTestPath()
  108. try! realm.transaction {
  109. var obj = SwiftRLMIntObject()
  110. obj.intCol = 2;
  111. realm.add(obj)
  112. obj = SwiftRLMIntObject()
  113. obj.intCol = 1;
  114. realm.add(obj)
  115. }
  116. }
  117. waitForExpectations(timeout: 2.0, handler: nil)
  118. token.invalidate()
  119. }
  120. func testRealmIsUpdatedImmediatelyAfterBackgroundUpdate() {
  121. let realm = realmWithTestPath()
  122. let notificationFired = expectation(description: "notification fired")
  123. let token = realm.addNotificationBlock { note, realm in
  124. XCTAssertNotNil(realm, "Realm should not be nil")
  125. notificationFired.fulfill()
  126. }
  127. dispatchAsync {
  128. let realm = self.realmWithTestPath()
  129. let obj = SwiftRLMStringObject(value: ["string"])
  130. realm.beginWriteTransaction()
  131. realm.add(obj)
  132. try! realm.commitWriteTransaction()
  133. let objects = SwiftRLMStringObject.allObjects(in: realm)
  134. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
  135. XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
  136. }
  137. waitForExpectations(timeout: 2.0, handler: nil)
  138. token.invalidate()
  139. // get object
  140. let objects = SwiftRLMStringObject.allObjects(in: realm)
  141. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type RLMTestObject")
  142. XCTAssertEqual((objects[0] as! SwiftRLMStringObject).stringCol, "string", "Value of first column should be 'string'")
  143. }
  144. // Objective-C models
  145. func testRealmAddAndRemoveObjects_objc() {
  146. let realm = realmWithTestPath()
  147. realm.beginWriteTransaction()
  148. _ = StringObject.create(in: realm, withValue: ["a"])
  149. _ = StringObject.create(in: realm, withValue: ["b"])
  150. _ = StringObject.create(in: realm, withValue: ["c"])
  151. XCTAssertEqual(StringObject.allObjects(in: realm).count, UInt(3), "Expecting 3 objects")
  152. try! realm.commitWriteTransaction()
  153. // test again after write transaction
  154. var objects = StringObject.allObjects(in: realm)
  155. XCTAssertEqual(objects.count, UInt(3), "Expecting 3 objects")
  156. XCTAssertEqual((objects[0] as! StringObject).stringCol!, "a", "Expecting column to be 'a'")
  157. realm.beginWriteTransaction()
  158. realm.delete(objects[2] as! StringObject)
  159. realm.delete(objects[0] as! StringObject)
  160. XCTAssertEqual(StringObject.allObjects(in: realm).count, UInt(1), "Expecting 1 object")
  161. try! realm.commitWriteTransaction()
  162. objects = StringObject.allObjects(in: realm)
  163. XCTAssertEqual(objects.count, UInt(1), "Expecting 1 object")
  164. XCTAssertEqual((objects[0] as! StringObject).stringCol!, "b", "Expecting column to be 'b'")
  165. }
  166. func testRealmIsUpdatedAfterBackgroundUpdate_objc() {
  167. let realm = realmWithTestPath()
  168. // we have two notifications, one for opening the realm, and a second when performing our transaction
  169. let notificationFired = expectation(description: "notification fired")
  170. let token = realm.addNotificationBlock { note, realm in
  171. XCTAssertNotNil(realm, "Realm should not be nil")
  172. if note == RLMNotification.DidChange {
  173. notificationFired.fulfill()
  174. }
  175. }
  176. dispatchAsync {
  177. let realm = self.realmWithTestPath()
  178. realm.beginWriteTransaction()
  179. _ = StringObject.create(in: realm, withValue: ["string"])
  180. try! realm.commitWriteTransaction()
  181. }
  182. waitForExpectations(timeout: 2.0, handler: nil)
  183. token.invalidate()
  184. // get object
  185. let objects = StringObject.allObjects(in: realm)
  186. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
  187. XCTAssertEqual((objects[0] as! StringObject).stringCol!, "string", "Value of first column should be 'string'")
  188. }
  189. func testRealmIsUpdatedImmediatelyAfterBackgroundUpdate_objc() {
  190. let realm = realmWithTestPath()
  191. // we have two notifications, one for opening the realm, and a second when performing our transaction
  192. let notificationFired = expectation(description: "notification fired")
  193. let token = realm.addNotificationBlock { note, realm in
  194. XCTAssertNotNil(realm, "Realm should not be nil")
  195. notificationFired.fulfill()
  196. }
  197. dispatchAsync {
  198. let realm = self.realmWithTestPath()
  199. let obj = StringObject(value: ["string"])
  200. try! realm.transaction {
  201. realm.add(obj)
  202. }
  203. let objects = StringObject.allObjects(in: realm)
  204. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type StringObject")
  205. XCTAssertEqual((objects[0] as! StringObject).stringCol!, "string", "Value of first column should be 'string'")
  206. }
  207. waitForExpectations(timeout: 2.0, handler: nil)
  208. token.invalidate()
  209. // get object
  210. let objects = StringObject.allObjects(in: realm)
  211. XCTAssertEqual(objects.count, UInt(1), "There should be 1 object of type RLMTestObject")
  212. XCTAssertEqual((objects[0] as! StringObject).stringCol!, "string", "Value of first column should be 'string'")
  213. }
  214. }