SwiftSchemaTests.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 Realm
  20. import Realm.Private
  21. import RealmTestSupport
  22. class InitLinkedToClass: RLMObject {
  23. @objc dynamic var value: SwiftRLMIntObject! = SwiftRLMIntObject(value: [0])
  24. }
  25. class SwiftRLMNonDefaultObject: RLMObject {
  26. @objc dynamic var value = 0
  27. public override class func shouldIncludeInDefaultSchema() -> Bool {
  28. return false
  29. }
  30. }
  31. class SwiftRLMLinkedNonDefaultObject: RLMObject {
  32. @objc dynamic var obj: SwiftRLMNonDefaultObject?
  33. public override class func shouldIncludeInDefaultSchema() -> Bool {
  34. return false
  35. }
  36. }
  37. class SwiftRLMNonDefaultArrayObject: RLMObject {
  38. @objc dynamic var array = RLMArray<SwiftRLMNonDefaultObject>(objectClassName: SwiftRLMNonDefaultObject.className())
  39. public override class func shouldIncludeInDefaultSchema() -> Bool {
  40. return false
  41. }
  42. }
  43. class SwiftRLMMutualLink1Object: RLMObject {
  44. @objc dynamic var object: SwiftRLMMutualLink2Object?
  45. public override class func shouldIncludeInDefaultSchema() -> Bool {
  46. return false
  47. }
  48. }
  49. class SwiftRLMMutualLink2Object: RLMObject {
  50. @objc dynamic var object: SwiftRLMMutualLink1Object?
  51. public override class func shouldIncludeInDefaultSchema() -> Bool {
  52. return false
  53. }
  54. }
  55. class IgnoredLinkPropertyObject : RLMObject {
  56. @objc dynamic var value = 0
  57. var obj = SwiftRLMIntObject()
  58. override class func ignoredProperties() -> [String] {
  59. return ["obj"]
  60. }
  61. }
  62. class SwiftRLMRecursingSchemaTestObject : RLMObject {
  63. @objc dynamic var propertyWithIllegalDefaultValue: SwiftRLMIntObject? = {
  64. if mayAccessSchema {
  65. let realm = RLMRealm.default()
  66. return SwiftRLMIntObject.allObjects().firstObject() as! SwiftRLMIntObject?
  67. } else {
  68. return nil
  69. }
  70. }()
  71. static var mayAccessSchema = false
  72. }
  73. class InvalidArrayType: FakeObject {
  74. @objc dynamic var array = RLMArray<SwiftRLMIntObject>(objectClassName: "invalid class")
  75. }
  76. class InitAppendsToArrayProperty : RLMObject {
  77. @objc dynamic var propertyWithIllegalDefaultValue: RLMArray<InitAppendsToArrayValue> = {
  78. if mayAppend {
  79. let array = RLMArray<InitAppendsToArrayValue>(objectClassName: InitAppendsToArrayValue.className())
  80. array.add(InitAppendsToArrayValue())
  81. return array
  82. } else {
  83. return RLMArray<InitAppendsToArrayValue>(objectClassName: InitAppendsToArrayValue.className())
  84. }
  85. }()
  86. static var mayAppend = false
  87. }
  88. class InitAppendsToArrayValue : RLMObject {
  89. @objc dynamic var value: Int = 0
  90. }
  91. class SwiftRLMSchemaTests: RLMMultiProcessTestCase {
  92. func testWorksAtAll() {
  93. if isParent {
  94. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  95. }
  96. }
  97. func testSchemaInitWithLinkedToObjectUsingInitWithValue() {
  98. if isParent {
  99. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  100. return
  101. }
  102. let config = RLMRealmConfiguration.default()
  103. config.objectClasses = [IgnoredLinkPropertyObject.self]
  104. config.inMemoryIdentifier = #function
  105. let r = try! RLMRealm(configuration: config)
  106. try! r.transaction {
  107. _ = IgnoredLinkPropertyObject.create(in: r, withValue: [1])
  108. }
  109. }
  110. func testCreateUnmanagedObjectWithUninitializedSchema() {
  111. if isParent {
  112. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  113. return
  114. }
  115. // Object in default schema
  116. _ = SwiftRLMIntObject()
  117. // Object not in default schema
  118. _ = SwiftRLMNonDefaultObject()
  119. }
  120. func testCreateUnmanagedObjectWithNestedObjectWithUninitializedSchema() {
  121. if isParent {
  122. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  123. return
  124. }
  125. // Objects in default schema
  126. // Should not throw (or crash) despite creating an object with an
  127. // unintialized schema during schema init
  128. _ = InitLinkedToClass()
  129. // Again with an object that links to an unintialized type
  130. // rather than creating one
  131. _ = SwiftRLMCompanyObject()
  132. // Objects not in default schema
  133. _ = SwiftRLMLinkedNonDefaultObject(value: [[1]])
  134. _ = SwiftRLMNonDefaultArrayObject(value: [[[1]]])
  135. _ = SwiftRLMMutualLink1Object(value: [[[:]]])
  136. }
  137. func testCreateUnmanagedObjectWhichCreatesAnotherClassViaInitWithValueDuringSchemaInit() {
  138. if isParent {
  139. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  140. return
  141. }
  142. _ = InitLinkedToClass(value: [[0]])
  143. _ = SwiftRLMCompanyObject(value: [[["Jaden", 20, false]]])
  144. }
  145. func testInitUnmanagedObjectNotInClassSubsetDuringSchemaInit() {
  146. if isParent {
  147. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  148. return
  149. }
  150. let config = RLMRealmConfiguration.default()
  151. config.objectClasses = [IgnoredLinkPropertyObject.self]
  152. config.inMemoryIdentifier = #function
  153. _ = try! RLMRealm(configuration: config)
  154. let r = try! RLMRealm(configuration: RLMRealmConfiguration.default())
  155. try! r.transaction {
  156. _ = IgnoredLinkPropertyObject.create(in: r, withValue: [1])
  157. }
  158. }
  159. func testPreventsDeadLocks() {
  160. if isParent {
  161. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  162. return
  163. }
  164. SwiftRLMRecursingSchemaTestObject.mayAccessSchema = true
  165. assertThrowsWithReasonMatching(RLMSchema.shared(), ".*recursive.*")
  166. }
  167. func testAccessSchemaCreatesObjectWhichAttempsInsertionsToArrayProperty() {
  168. if isParent {
  169. XCTAssertEqual(0, runChildAndWait(), "Tests in child process failed")
  170. return
  171. }
  172. // This is different from the above tests in that it is a to-many link
  173. // and it only occurs while the schema is initializing
  174. InitAppendsToArrayProperty.mayAppend = true
  175. assertThrowsWithReasonMatching(RLMSchema.shared(), ".*unless the schema is initialized.*")
  176. }
  177. func testInvalidObjectTypeForRLMArray() {
  178. RLMSetTreatFakeObjectAsRLMObject(true)
  179. assertThrowsWithReasonMatching(RLMObjectSchema(forObjectClass: InvalidArrayType.self),
  180. "RLMArray\\<invalid class\\>")
  181. RLMSetTreatFakeObjectAsRLMObject(false)
  182. }
  183. }