An amazing project that generates micro reports from tournament results
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

712 lines
30 KiB

////////////////////////////////////////////////////////////////////////////
//
// 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 DynamicDefaultObject: 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", "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\tfloatCol = 1\\.23;\n\tdoubleCol = 12\\.3;\n\tstringCol = a;\n\tbinaryCol = <61 — 1 total bytes>;\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 = LinkToRenamedProperties1()
renamedObject.linkA = RenamedProperties1()
assertMatches(renamedObject.description, "LinkToRenamedProperties1 \\{\n\tlinkA = RenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<RenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToRenamedProperties1> <0x[0-9a-f]+> \\(\n\n\\)")
let realm = try! Realm()
try! realm.write { realm.add(renamedObject) }
assertMatches(renamedObject.description, "LinkToRenamedProperties1 \\{\n\tlinkA = RenamedProperties1 \\{\n\t\tpropA = 0;\n\t\tpropB = ;\n\t\\};\n\tlinkB = \\(null\\);\n\tarray1 = List<RenamedProperties1> <0x[0-9a-f]+> \\(\n\t\n\t\\);\n\\}")
assertMatches(renamedObject.linkA!.linking1.description, "LinkingObjects<LinkToRenamedProperties1> <0x[0-9a-f]+> \\(\n\t\\[0\\] LinkToRenamedProperties1 \\{\n\t\tlinkA = RenamedProperties1 \\{\n\t\t\tpropA = 0;\n\t\t\tpropB = ;\n\t\t\\};\n\t\tlinkB = \\(null\\);\n\t\tarray1 = List<RenamedProperties1> <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: DynamicDefaultObject, _ obj2: DynamicDefaultObject) {
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(DynamicDefaultObject(), DynamicDefaultObject())
let realm = try! Realm()
try! realm.write {
assertDifferentPropertyValues(realm.create(DynamicDefaultObject.self),
realm.create(DynamicDefaultObject.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)!
XCTAssertTrue(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())
try! Realm().write {
let persistedObject = try! Realm().create(SwiftObject.self, value: [:])
test(persistedObject)
}
}
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
object.numCol = 42
}
XCTAssertEqual("Hello world!", object.stringCol)
XCTAssertEqual(now, object.dateCol)
XCTAssertEqual(data, object.dataCol)
XCTAssertEqual(42, object.numCol)
}
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)
}
}