123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796 |
- ////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2015 Realm Inc.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- ////////////////////////////////////////////////////////////////////////////
- import XCTest
- import RealmSwift
- import Foundation
- private var dynamicDefaultSeed = 0
- private func nextDynamicDefaultSeed() -> Int {
- dynamicDefaultSeed += 1
- return dynamicDefaultSeed
- }
- class SwiftDynamicDefaultObject: Object {
- @objc dynamic var intCol = nextDynamicDefaultSeed()
- @objc dynamic var floatCol = Float(nextDynamicDefaultSeed())
- @objc dynamic var doubleCol = Double(nextDynamicDefaultSeed())
- @objc dynamic var dateCol = Date(timeIntervalSinceReferenceDate: TimeInterval(nextDynamicDefaultSeed()))
- @objc dynamic var stringCol = UUID().uuidString
- @objc dynamic var binaryCol = UUID().uuidString.data(using: .utf8)
- override static func primaryKey() -> String? {
- return "intCol"
- }
- }
- class ObjectTests: TestCase {
- // init() Tests are in ObjectCreationTests.swift
- // init(value:) tests are in ObjectCreationTests.swift
- func testRealm() {
- let standalone = SwiftStringObject()
- XCTAssertNil(standalone.realm)
- let realm = try! Realm()
- var persisted: SwiftStringObject!
- try! realm.write {
- persisted = realm.create(SwiftStringObject.self, value: [:])
- XCTAssertNotNil(persisted.realm)
- XCTAssertEqual(realm, persisted.realm!)
- }
- XCTAssertNotNil(persisted.realm)
- XCTAssertEqual(realm, persisted.realm!)
- dispatchSyncNewThread {
- autoreleasepool {
- XCTAssertNotEqual(try! Realm(), persisted.realm!)
- }
- }
- }
- func testObjectSchema() {
- let object = SwiftObject()
- let schema = object.objectSchema
- XCTAssert(schema as AnyObject is ObjectSchema)
- XCTAssert(schema.properties as AnyObject is [Property])
- XCTAssertEqual(schema.className, "SwiftObject")
- XCTAssertEqual(schema.properties.map { $0.name },
- ["boolCol", "intCol", "intEnumCol", "floatCol", "doubleCol", "stringCol", "binaryCol", "dateCol", "objectCol", "arrayCol"]
- )
- }
- func testObjectSchemaForObjectWithConvenienceInitializer() {
- let object = SwiftConvenienceInitializerObject(stringCol: "abc")
- let schema = object.objectSchema
- XCTAssert(schema as AnyObject is ObjectSchema)
- XCTAssert(schema.properties as AnyObject is [Property])
- XCTAssertEqual(schema.className, "SwiftConvenienceInitializerObject")
- XCTAssertEqual(schema.properties.map { $0.name }, ["stringCol"])
- }
- func testSharedSchemaUnmanaged() {
- let object = SwiftObject()
- XCTAssertEqual(type(of: object).sharedSchema(), SwiftObject.sharedSchema())
- }
- func testSharedSchemaManaged() {
- let object = SwiftObject()
- XCTAssertEqual(type(of: object).sharedSchema(), SwiftObject.sharedSchema())
- }
- func testInvalidated() {
- let object = SwiftObject()
- XCTAssertFalse(object.isInvalidated)
- let realm = try! Realm()
- try! realm.write {
- realm.add(object)
- XCTAssertFalse(object.isInvalidated)
- }
- try! realm.write {
- realm.deleteAll()
- XCTAssertTrue(object.isInvalidated)
- }
- XCTAssertTrue(object.isInvalidated)
- }
- func testDescription() {
- let object = SwiftObject()
- // swiftlint:disable line_length
- assertMatches(object.description, "SwiftObject \\{\n\tboolCol = 0;\n\tintCol = 123;\n\tintEnumCol = 1;\n\tfloatCol = 1\\.23;\n\tdoubleCol = 12\\.3;\n\tstringCol = a;\n\tbinaryCol = <.*61.*>;\n\tdateCol = 1970-01-01 00:00:01 \\+0000;\n\tobjectCol = SwiftBoolObject \\{\n\t\tboolCol = 0;\n\t\\};\n\tarrayCol = List<SwiftBoolObject> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
- let recursiveObject = SwiftRecursiveObject()
- recursiveObject.objects.append(recursiveObject)
- assertMatches(recursiveObject.description, "SwiftRecursiveObject \\{\n\tobjects = List<SwiftRecursiveObject> <0x[0-9a-f]+> \\(\n\t\t\\[0\\] SwiftRecursiveObject \\{\n\t\t\tobjects = List<SwiftRecursiveObject> <0x[0-9a-f]+> \\(\n\t\t\t\t\\[0\\] SwiftRecursiveObject \\{\n\t\t\t\t\tobjects = <Maximum depth exceeded>;\n\t\t\t\t\\}\n\t\t\t\\);\n\t\t\\}\n\t\\);\n\\}")
- let renamedObject = LinkToSwiftRenamedProperties1()
- renamedObject.linkA = SwiftRenamedProperties1()
- assertMatches(renamedObject.description, "LinkToSwiftRenamedProperties1 \\{\n\tlinkA = SwiftRenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
- assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToSwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\n\\)")
- let realm = try! Realm()
- try! realm.write { realm.add(renamedObject) }
- assertMatches(renamedObject.description, "LinkToSwiftRenamedProperties1 \\{\n\tlinkA = SwiftRenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
- assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToSwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\\[0\\] LinkToSwiftRenamedProperties1 \\{\n\t\tlinkA = SwiftRenamedProperties1 \\{\n\t\t\tpropA = 0;\n\t\t\tpropB = ;\n\t\t\\};\n\t\tlinkB = \\(null\\);\n\t\tarray1 = List<SwiftRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\t\n\t\t\\);\n\t\\}\n\\)")
- // swiftlint:enable line_length
- }
- func testSchemaHasPrimaryKey() {
- XCTAssertNil(Object.primaryKey(), "primary key should default to nil")
- XCTAssertNil(SwiftStringObject.primaryKey())
- XCTAssertNil(SwiftStringObject().objectSchema.primaryKeyProperty)
- XCTAssertEqual(SwiftPrimaryStringObject.primaryKey()!, "stringCol")
- XCTAssertEqual(SwiftPrimaryStringObject().objectSchema.primaryKeyProperty!.name, "stringCol")
- }
- func testCannotUpdatePrimaryKey() {
- let realm = self.realmWithTestPath()
- let primaryKeyReason = "Primary key can't be changed .*after an object is inserted."
- let intObj = SwiftPrimaryIntObject()
- intObj.intCol = 1
- intObj.intCol = 0; // can change primary key unattached
- XCTAssertEqual(0, intObj.intCol)
- let optionalIntObj = SwiftPrimaryOptionalIntObject()
- optionalIntObj.intCol.value = 1
- optionalIntObj.intCol.value = 0; // can change primary key unattached
- XCTAssertEqual(0, optionalIntObj.intCol.value)
- let stringObj = SwiftPrimaryStringObject()
- stringObj.stringCol = "a"
- stringObj.stringCol = "b" // can change primary key unattached
- XCTAssertEqual("b", stringObj.stringCol)
- try! realm.write {
- realm.add(intObj)
- assertThrows(intObj.intCol = 2, reasonMatching: primaryKeyReason)
- assertThrows(intObj["intCol"] = 2, reasonMatching: primaryKeyReason)
- assertThrows(intObj.setValue(2, forKey: "intCol"), reasonMatching: primaryKeyReason)
- realm.add(optionalIntObj)
- assertThrows(optionalIntObj.intCol.value = 2, reasonMatching: "Cannot modify primary key")
- assertThrows(optionalIntObj["intCol"] = 2, reasonMatching: primaryKeyReason)
- assertThrows(optionalIntObj.setValue(2, forKey: "intCol"), reasonMatching: "Cannot modify primary key")
- realm.add(stringObj)
- assertThrows(stringObj.stringCol = "c", reasonMatching: primaryKeyReason)
- assertThrows(stringObj["stringCol"] = "c", reasonMatching: primaryKeyReason)
- assertThrows(stringObj.setValue("c", forKey: "stringCol"), reasonMatching: primaryKeyReason)
- }
- }
- func testIgnoredProperties() {
- XCTAssertEqual(Object.ignoredProperties(), [], "ignored properties should default to []")
- XCTAssertEqual(SwiftIgnoredPropertiesObject.ignoredProperties().count, 2)
- XCTAssertNil(SwiftIgnoredPropertiesObject().objectSchema["runtimeProperty"])
- }
- func testIndexedProperties() {
- XCTAssertEqual(Object.indexedProperties(), [], "indexed properties should default to []")
- XCTAssertEqual(SwiftIndexedPropertiesObject.indexedProperties().count, 8)
- let objectSchema = SwiftIndexedPropertiesObject().objectSchema
- XCTAssertTrue(objectSchema["stringCol"]!.isIndexed)
- XCTAssertTrue(objectSchema["intCol"]!.isIndexed)
- XCTAssertTrue(objectSchema["int8Col"]!.isIndexed)
- XCTAssertTrue(objectSchema["int16Col"]!.isIndexed)
- XCTAssertTrue(objectSchema["int32Col"]!.isIndexed)
- XCTAssertTrue(objectSchema["int64Col"]!.isIndexed)
- XCTAssertTrue(objectSchema["boolCol"]!.isIndexed)
- XCTAssertTrue(objectSchema["dateCol"]!.isIndexed)
- XCTAssertFalse(objectSchema["floatCol"]!.isIndexed)
- XCTAssertFalse(objectSchema["doubleCol"]!.isIndexed)
- XCTAssertFalse(objectSchema["dataCol"]!.isIndexed)
- }
- func testIndexedOptionalProperties() {
- XCTAssertEqual(Object.indexedProperties(), [], "indexed properties should default to []")
- XCTAssertEqual(SwiftIndexedOptionalPropertiesObject.indexedProperties().count, 8)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalStringCol"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalDateCol"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalBoolCol"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalIntCol"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalInt8Col"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalInt16Col"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalInt32Col"]!.isIndexed)
- XCTAssertTrue(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalInt64Col"]!.isIndexed)
- XCTAssertFalse(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalDataCol"]!.isIndexed)
- XCTAssertFalse(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalFloatCol"]!.isIndexed)
- XCTAssertFalse(SwiftIndexedOptionalPropertiesObject().objectSchema["optionalDoubleCol"]!.isIndexed)
- }
- func testDynamicDefaultPropertyValues() {
- func assertDifferentPropertyValues(_ obj1: SwiftDynamicDefaultObject, _ obj2: SwiftDynamicDefaultObject) {
- XCTAssertNotEqual(obj1.intCol, obj2.intCol)
- XCTAssertNotEqual(obj1.floatCol, obj2.floatCol)
- XCTAssertNotEqual(obj1.doubleCol, obj2.doubleCol)
- XCTAssertNotEqual(obj1.dateCol.timeIntervalSinceReferenceDate, obj2.dateCol.timeIntervalSinceReferenceDate,
- accuracy: 0.01)
- XCTAssertNotEqual(obj1.stringCol, obj2.stringCol)
- XCTAssertNotEqual(obj1.binaryCol, obj2.binaryCol)
- }
- assertDifferentPropertyValues(SwiftDynamicDefaultObject(), SwiftDynamicDefaultObject())
- let realm = try! Realm()
- try! realm.write {
- assertDifferentPropertyValues(realm.create(SwiftDynamicDefaultObject.self),
- realm.create(SwiftDynamicDefaultObject.self))
- }
- }
- func testValueForKey() {
- let test: (SwiftObject) -> Void = { object in
- XCTAssertEqual(object.value(forKey: "boolCol") as! Bool?, false)
- XCTAssertEqual(object.value(forKey: "intCol") as! Int?, 123)
- XCTAssertEqual(object.value(forKey: "floatCol") as! Float?, 1.23 as Float)
- XCTAssertEqual(object.value(forKey: "doubleCol") as! Double?, 12.3)
- XCTAssertEqual(object.value(forKey: "stringCol") as! String?, "a")
- let expected = object.value(forKey: "binaryCol") as! Data
- let actual = "a".data(using: String.Encoding.utf8)!
- XCTAssertEqual(expected, actual)
- XCTAssertEqual(object.value(forKey: "dateCol") as! Date?, Date(timeIntervalSince1970: 1))
- XCTAssertEqual((object.value(forKey: "objectCol")! as! SwiftBoolObject).boolCol, false)
- XCTAssert(object.value(forKey: "arrayCol")! is List<SwiftBoolObject>)
- }
- test(SwiftObject())
- let realm = try! Realm()
- try! realm.write {
- test(realm.create(SwiftObject.self, value: [:]))
- let addedObj = SwiftObject()
- realm.add(addedObj)
- test(addedObj)
- }
- }
- func testValueForKeyOptionals() {
- let test: (SwiftOptionalObject) -> Void = { object in
- XCTAssertNil(object.value(forKey: "optNSStringCol"))
- XCTAssertNil(object.value(forKey: "optStringCol"))
- XCTAssertNil(object.value(forKey: "optBinaryCol"))
- XCTAssertNil(object.value(forKey: "optDateCol"))
- XCTAssertNil(object.value(forKey: "optIntCol"))
- XCTAssertNil(object.value(forKey: "optInt8Col"))
- XCTAssertNil(object.value(forKey: "optInt16Col"))
- XCTAssertNil(object.value(forKey: "optInt32Col"))
- XCTAssertNil(object.value(forKey: "optInt64Col"))
- XCTAssertNil(object.value(forKey: "optFloatCol"))
- XCTAssertNil(object.value(forKey: "optDoubleCol"))
- XCTAssertNil(object.value(forKey: "optBoolCol"))
- XCTAssertNil(object.value(forKey: "optEnumCol"))
- }
- test(SwiftOptionalObject())
- let realm = try! Realm()
- try! realm.write {
- test(realm.create(SwiftOptionalObject.self, value: [:]))
- let addedObj = SwiftOptionalObject()
- realm.add(addedObj)
- test(addedObj)
- }
- }
- func testValueForKeyList() {
- let test: (SwiftListObject) -> Void = { object in
- XCTAssertNil((object.value(forKey: "int") as! List<Int>).first)
- XCTAssertNil((object.value(forKey: "int8") as! List<Int8>).first)
- XCTAssertNil((object.value(forKey: "int16") as! List<Int16>).first)
- XCTAssertNil((object.value(forKey: "int32") as! List<Int32>).first)
- XCTAssertNil((object.value(forKey: "int64") as! List<Int64>).first)
- XCTAssertNil((object.value(forKey: "float") as! List<Float>).first)
- XCTAssertNil((object.value(forKey: "double") as! List<Double>).first)
- XCTAssertNil((object.value(forKey: "string") as! List<String>).first)
- XCTAssertNil((object.value(forKey: "data") as! List<Data>).first)
- XCTAssertNil((object.value(forKey: "date") as! List<Date>).first)
- // The `as Any?` casts below are only to silence the warning about it
- // happening implicitly and are not functionally required
- XCTAssertNil((object.value(forKey: "intOpt") as! List<Int?>).first as Any?)
- XCTAssertNil((object.value(forKey: "int8Opt") as! List<Int8?>).first as Any?)
- XCTAssertNil((object.value(forKey: "int16Opt") as! List<Int16?>).first as Any?)
- XCTAssertNil((object.value(forKey: "int32Opt") as! List<Int32?>).first as Any?)
- XCTAssertNil((object.value(forKey: "int64Opt") as! List<Int64?>).first as Any?)
- XCTAssertNil((object.value(forKey: "floatOpt") as! List<Float?>).first as Any?)
- XCTAssertNil((object.value(forKey: "doubleOpt") as! List<Double?>).first as Any?)
- XCTAssertNil((object.value(forKey: "stringOpt") as! List<String?>).first as Any?)
- XCTAssertNil((object.value(forKey: "dataOpt") as! List<Data?>).first as Any?)
- XCTAssertNil((object.value(forKey: "dateOpt") as! List<Date?>).first as Any?)
- }
- test(SwiftListObject())
- let realm = try! Realm()
- try! realm.write {
- test(realm.create(SwiftListObject.self, value: [:]))
- let addedObj = SwiftListObject()
- realm.add(addedObj)
- test(addedObj)
- }
- }
- func testValueForKeyLinkingObjects() {
- let test: (SwiftDogObject) -> Void = { object in
- let owners = object.value(forKey: "owners") as! LinkingObjects<SwiftOwnerObject>
- if object.realm != nil {
- XCTAssertEqual(owners.first!.name, "owner name")
- }
- }
- let dog = SwiftDogObject()
- let owner = SwiftOwnerObject(value: ["owner name", dog])
- test(dog)
- let realm = try! Realm()
- try! realm.write {
- test(realm.create(SwiftOwnerObject.self, value: owner).dog!)
- realm.add(owner)
- test(dog)
- }
- }
- func testSettingUnmanagedObjectValuesWithSwiftDictionary() {
- let json: [String: Any] = ["name": "foo", "array": [["stringCol": "bar"]], "intArray": [["intCol": 50]]]
- let object = SwiftArrayPropertyObject()
- json.keys.forEach { key in
- object.setValue(json[key], forKey: key)
- }
- XCTAssertEqual(object.name, "foo")
- XCTAssertEqual(object.array[0].stringCol, "bar")
- XCTAssertEqual(object.intArray[0].intCol, 50)
- }
- func testSettingUnmanagedObjectValuesWithBadSwiftDictionary() {
- let json: [String: Any] = ["name": "foo", "array": [["stringCol": NSObject()]], "intArray": [["intCol": 50]]]
- let object = SwiftArrayPropertyObject()
- assertThrows({ json.keys.forEach { key in object.setValue(json[key], forKey: key) } }())
- }
- func setAndTestAllTypes(_ setter: (SwiftObject, Any?, String) -> Void,
- getter: (SwiftObject, String) -> (Any?), object: SwiftObject) {
- setter(object, true, "boolCol")
- XCTAssertEqual(getter(object, "boolCol") as! Bool?, true)
- setter(object, 321, "intCol")
- XCTAssertEqual(getter(object, "intCol") as! Int?, 321)
- setter(object, NSNumber(value: 32.1 as Float), "floatCol")
- XCTAssertEqual(getter(object, "floatCol") as! Float?, 32.1 as Float)
- setter(object, 3.21, "doubleCol")
- XCTAssertEqual(getter(object, "doubleCol") as! Double?, 3.21)
- setter(object, "z", "stringCol")
- XCTAssertEqual(getter(object, "stringCol") as! String?, "z")
- setter(object, "z".data(using: String.Encoding.utf8)! as Data, "binaryCol")
- let gotData = getter(object, "binaryCol") as! Data
- XCTAssertTrue(gotData == "z".data(using: String.Encoding.utf8)!)
- setter(object, Date(timeIntervalSince1970: 333), "dateCol")
- XCTAssertEqual(getter(object, "dateCol") as! Date?, Date(timeIntervalSince1970: 333))
- let boolObject = SwiftBoolObject(value: [true])
- setter(object, boolObject, "objectCol")
- assertEqual(getter(object, "objectCol") as? SwiftBoolObject, boolObject)
- XCTAssertEqual((getter(object, "objectCol") as! SwiftBoolObject).boolCol, true)
- let list = List<SwiftBoolObject>()
- list.append(boolObject)
- setter(object, list, "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).count, 1)
- assertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).first!, boolObject)
- list.removeAll()
- setter(object, list, "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).count, 0)
- setter(object, [boolObject], "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).count, 1)
- assertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).first!, boolObject)
- setter(object, nil, "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).count, 0)
- setter(object, [boolObject], "arrayCol")
- setter(object, NSNull(), "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<SwiftBoolObject>).count, 0)
- }
- func dynamicSetAndTestAllTypes(_ setter: (DynamicObject, Any?, String) -> Void,
- getter: (DynamicObject, String) -> (Any?), object: DynamicObject,
- boolObject: DynamicObject) {
- setter(object, true, "boolCol")
- XCTAssertEqual((getter(object, "boolCol") as! Bool), true)
- setter(object, 321, "intCol")
- XCTAssertEqual((getter(object, "intCol") as! Int), 321)
- setter(object, NSNumber(value: 32.1 as Float), "floatCol")
- XCTAssertEqual((getter(object, "floatCol") as! Float), 32.1 as Float)
- setter(object, 3.21, "doubleCol")
- XCTAssertEqual((getter(object, "doubleCol") as! Double), 3.21)
- setter(object, "z", "stringCol")
- XCTAssertEqual((getter(object, "stringCol") as! String), "z")
- setter(object, "z".data(using: String.Encoding.utf8)! as Data, "binaryCol")
- let gotData = getter(object, "binaryCol") as! Data
- XCTAssertTrue(gotData == "z".data(using: String.Encoding.utf8)!)
- setter(object, Date(timeIntervalSince1970: 333), "dateCol")
- XCTAssertEqual((getter(object, "dateCol") as! Date), Date(timeIntervalSince1970: 333))
- setter(object, boolObject, "objectCol")
- assertEqual((getter(object, "objectCol") as! DynamicObject), boolObject)
- XCTAssertEqual(((getter(object, "objectCol") as! DynamicObject)["boolCol"] as! Bool), true)
- setter(object, [boolObject], "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<DynamicObject>).count, 1)
- assertEqual((getter(object, "arrayCol") as! List<DynamicObject>).first!, boolObject)
- let list = getter(object, "arrayCol") as! List<DynamicObject>
- list.removeAll()
- setter(object, list, "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<DynamicObject>).count, 0)
- setter(object, [boolObject], "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<DynamicObject>).count, 1)
- assertEqual((getter(object, "arrayCol") as! List<DynamicObject>).first!, boolObject)
- setter(object, nil, "arrayCol")
- XCTAssertEqual((getter(object, "arrayCol") as! List<DynamicObject>).count, 0)
- }
- // Yields a read-write migration `SwiftObject` to the given block
- private func withMigrationObject(block: @escaping ((MigrationObject, Migration) -> Void)) {
- autoreleasepool {
- let realm = self.realmWithTestPath()
- try! realm.write {
- _ = realm.create(SwiftObject.self)
- }
- }
- autoreleasepool {
- var enumerated = false
- let configuration = Realm.Configuration(schemaVersion: 1, migrationBlock: { migration, _ in
- migration.enumerateObjects(ofType: SwiftObject.className()) { _, newObject in
- if let newObject = newObject {
- block(newObject, migration)
- enumerated = true
- }
- }
- })
- self.realmWithTestPath(configuration: configuration)
- XCTAssert(enumerated)
- }
- }
- func testSetValueForKey() {
- let setter: (Object, Any?, String) -> Void = { object, value, key in
- object.setValue(value, forKey: key)
- return
- }
- let getter: (Object, String) -> (Any?) = { object, key in
- object.value(forKey: key)
- }
- withMigrationObject { migrationObject, migration in
- let boolObject = migration.create("SwiftBoolObject", value: [true])
- self.dynamicSetAndTestAllTypes(setter, getter: getter, object: migrationObject, boolObject: boolObject)
- }
- setAndTestAllTypes(setter, getter: getter, object: SwiftObject())
- try! Realm().write {
- let persistedObject = try! Realm().create(SwiftObject.self, value: [:])
- self.setAndTestAllTypes(setter, getter: getter, object: persistedObject)
- }
- }
- func testSubscript() {
- let setter: (Object, Any?, String) -> Void = { object, value, key in
- object[key] = value
- return
- }
- let getter: (Object, String) -> (Any?) = { object, key in
- object[key]
- }
- withMigrationObject { migrationObject, migration in
- let boolObject = migration.create("SwiftBoolObject", value: [true])
- self.dynamicSetAndTestAllTypes(setter, getter: getter, object: migrationObject, boolObject: boolObject)
- }
- setAndTestAllTypes(setter, getter: getter, object: SwiftObject())
- try! Realm().write {
- let persistedObject = try! Realm().create(SwiftObject.self, value: [:])
- self.setAndTestAllTypes(setter, getter: getter, object: persistedObject)
- }
- }
- func testDynamicList() {
- let realm = try! Realm()
- let arrayObject = SwiftArrayPropertyObject()
- let str1 = SwiftStringObject()
- let str2 = SwiftStringObject()
- arrayObject.array.append(objectsIn: [str1, str2])
- try! realm.write {
- realm.add(arrayObject)
- }
- let dynamicArray = arrayObject.dynamicList("array")
- XCTAssertEqual(dynamicArray.count, 2)
- assertEqual(dynamicArray[0], str1)
- assertEqual(dynamicArray[1], str2)
- XCTAssertEqual(arrayObject.dynamicList("intArray").count, 0)
- assertThrows(arrayObject.dynamicList("noSuchList"))
- }
- func testObjectiveCTypeProperties() {
- let realm = try! Realm()
- var object: SwiftObjectiveCTypesObject!
- let now = NSDate()
- let data = "fizzbuzz".data(using: .utf8)! as Data as NSData
- try! realm.write {
- object = SwiftObjectiveCTypesObject()
- realm.add(object)
- object.stringCol = "Hello world!"
- object.dateCol = now
- object.dataCol = data
- }
- XCTAssertEqual("Hello world!", object.stringCol)
- XCTAssertEqual(now, object.dateCol)
- XCTAssertEqual(data, object.dataCol)
- }
- func testDeleteObservedObject() {
- let realm = try! Realm()
- realm.beginWrite()
- let object = realm.create(SwiftIntObject.self, value: [0])
- try! realm.commitWrite()
- let exp = expectation(description: "")
- let token = object.observe { change in
- if case .deleted = change {
- } else {
- XCTFail("expected .deleted, got \(change)")
- }
- exp.fulfill()
- }
- realm.beginWrite()
- realm.delete(object)
- try! realm.commitWrite()
- waitForExpectations(timeout: 2)
- token.invalidate()
- }
- func expectChange<T: Equatable, U: Equatable>(_ name: String, _ old: T?, _ new: U?) -> ((ObjectChange) -> Void) {
- let exp = expectation(description: "")
- return { change in
- if case .change(let properties) = change {
- XCTAssertEqual(properties.count, 1)
- if let prop = properties.first {
- XCTAssertEqual(prop.name, name)
- XCTAssertEqual(prop.oldValue as? T, old)
- XCTAssertEqual(prop.newValue as? U, new)
- }
- } else {
- XCTFail("expected .change, got \(change)")
- }
- exp.fulfill()
- }
- }
- func testModifyObservedObjectLocally() {
- let realm = try! Realm()
- realm.beginWrite()
- let object = realm.create(SwiftIntObject.self, value: [1])
- try! realm.commitWrite()
- let token = object.observe(expectChange("intCol", Int?.none, 2))
- try! realm.write {
- object.intCol = 2
- }
- waitForExpectations(timeout: 2)
- token.invalidate()
- }
- func testModifyObservedObjectRemotely() {
- let realm = try! Realm()
- realm.beginWrite()
- let object = realm.create(SwiftIntObject.self, value: [1])
- try! realm.commitWrite()
- let token = object.observe(expectChange("intCol", 1, 2))
- dispatchSyncNewThread {
- let realm = try! Realm()
- try! realm.write {
- realm.objects(SwiftIntObject.self).first!.intCol = 2
- }
- }
- realm.refresh()
- waitForExpectations(timeout: 0)
- token.invalidate()
- }
- func testListPropertyNotifications() {
- let realm = try! Realm()
- realm.beginWrite()
- let object = realm.create(SwiftRecursiveObject.self, value: [[]])
- try! realm.commitWrite()
- let token = object.observe(expectChange("objects", Int?.none, Int?.none))
- dispatchSyncNewThread {
- let realm = try! Realm()
- try! realm.write {
- let obj = realm.objects(SwiftRecursiveObject.self).first!
- obj.objects.append(obj)
- }
- }
- waitForExpectations(timeout: 2)
- token.invalidate()
- }
- func testOptionalPropertyNotifications() {
- let realm = try! Realm()
- let object = SwiftOptionalDefaultValuesObject()
- try! realm.write {
- realm.add(object)
- }
- var token = object.observe(expectChange("optIntCol", 1, 2))
- dispatchSyncNewThread {
- let realm = try! Realm()
- try! realm.write {
- realm.objects(SwiftOptionalDefaultValuesObject.self).first!.optIntCol.value = 2
- }
- }
- realm.refresh()
- waitForExpectations(timeout: 0)
- token.invalidate()
- token = object.observe(expectChange("optIntCol", 2, Int?.none))
- dispatchSyncNewThread {
- let realm = try! Realm()
- try! realm.write {
- realm.objects(SwiftOptionalDefaultValuesObject.self).first!.optIntCol.value = nil
- }
- }
- realm.refresh()
- waitForExpectations(timeout: 0)
- token.invalidate()
- token = object.observe(expectChange("optIntCol", Int?.none, 3))
- dispatchSyncNewThread {
- let realm = try! Realm()
- try! realm.write {
- realm.objects(SwiftOptionalDefaultValuesObject.self).first!.optIntCol.value = 3
- }
- }
- realm.refresh()
- waitForExpectations(timeout: 0)
- token.invalidate()
- }
- func testEqualityForObjectTypeWithPrimaryKey() {
- let realm = try! Realm()
- let pk = "123456"
- let testObject = SwiftPrimaryStringObject()
- testObject.stringCol = pk
- testObject.intCol = 12345
- let unmanaged = SwiftPrimaryStringObject()
- unmanaged.stringCol = pk
- unmanaged.intCol = 12345
- let otherObject = SwiftPrimaryStringObject()
- otherObject.stringCol = "not" + pk
- otherObject.intCol = 12345
- try! realm.write {
- realm.add([testObject, otherObject])
- }
- // Should not match an object that's not equal.
- XCTAssertNotEqual(testObject, otherObject)
- // Should not match an object whose fields are equal if it's not the same row in the database.
- XCTAssertNotEqual(testObject, unmanaged)
- // Should match an object that represents the same row.
- let retrievedObject = realm.object(ofType: SwiftPrimaryStringObject.self, forPrimaryKey: pk)!
- XCTAssertEqual(testObject, retrievedObject)
- XCTAssertEqual(testObject.hash, retrievedObject.hash)
- XCTAssertTrue(testObject.isSameObject(as: retrievedObject))
- }
- func testEqualityForObjectTypeWithoutPrimaryKey() {
- let realm = try! Realm()
- let pk = "123456"
- XCTAssertNil(SwiftStringObject.primaryKey())
- let testObject = SwiftStringObject()
- testObject.stringCol = pk
- let alias = testObject
- try! realm.write {
- realm.add(testObject)
- }
- XCTAssertEqual(testObject, alias)
- // Should not match an object even if it represents the same row.
- let retrievedObject = realm.objects(SwiftStringObject.self).first!
- XCTAssertNotEqual(testObject, retrievedObject)
- // Should be able to use `isSameObject(as:)` to check if same row in the database.
- XCTAssertTrue(testObject.isSameObject(as: retrievedObject))
- }
- func testRetrievingObjectWithRuntimeType() {
- let realm = try! Realm()
- let unmanagedStringObject = SwiftPrimaryStringObject()
- unmanagedStringObject.stringCol = UUID().uuidString
- let managedStringObject = SwiftPrimaryStringObject()
- managedStringObject.stringCol = UUID().uuidString
- // Add the object.
- try! realm.write {
- realm.add(managedStringObject)
- }
- // Shouldn't throw when using type(of:).
- XCTAssertNotNil(realm.object(ofType: type(of: unmanagedStringObject),
- forPrimaryKey: managedStringObject.stringCol))
- // Shouldn't throw when using type(of:).
- XCTAssertNotNil(realm.object(ofType: type(of: managedStringObject),
- forPrimaryKey: managedStringObject.stringCol))
- }
- func testRetrievingObjectsWithRuntimeType() {
- let realm = try! Realm()
- let unmanagedStringObject = SwiftStringObject()
- unmanagedStringObject.stringCol = "foo"
- let managedStringObject = SwiftStringObject()
- managedStringObject.stringCol = "bar"
- // Add the object.
- try! realm.write {
- realm.add(managedStringObject)
- }
- // Shouldn't throw when using type(of:).
- XCTAssertEqual(realm.objects(type(of: unmanagedStringObject)).count, 1)
- // Shouldn't throw when using type(of:).
- XCTAssertEqual(realm.objects(type(of: managedStringObject)).count, 1)
- }
- }
|