mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-09-10 20:02:02 +02:00
WIP
This commit is contained in:
@@ -24,11 +24,11 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import os
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
#if !SWIFT_PACKAGE
|
||||
|
||||
extension Bundle {
|
||||
@@ -196,7 +196,7 @@ final class TestLogger: CoreStoreLogger {
|
||||
|
||||
init(_ expectations: [Expectation: XCTestExpectation]) {
|
||||
|
||||
self.expectations = .init(initialState: expectations)
|
||||
self.expectations = .init(expectations)
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ final class TestLogger: CoreStoreLogger {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let expectations: OSAllocatedUnfairLock<[Expectation: XCTestExpectation]>
|
||||
private let expectations: Internals.Mutex<[Expectation: XCTestExpectation]>
|
||||
|
||||
private func fulfill(_ expectation: Expectation) {
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ class Person: CoreStoreObject {
|
||||
|
||||
class DynamicModelTests: BaseTestDataTestCase {
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDynamicModels_CanBeDeclaredCorrectly() {
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import CoreStore
|
||||
|
||||
final class FetchTests: BaseTestDataTestCase {
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchOneExisting() {
|
||||
|
||||
@@ -103,14 +104,14 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let persistentID = object.persistentID()
|
||||
let fetchExpectation = self.expectation(description: "fetch")
|
||||
var existing1: TestEntity1?
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
existing1 = transaction.fetchExisting(object)
|
||||
let existing1 = transaction.fetchExisting(persistentID)
|
||||
XCTAssertNotNil(existing1)
|
||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing1!.persistentID(), persistentID)
|
||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||
|
||||
try transaction.cancel()
|
||||
@@ -123,9 +124,9 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
|
||||
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1!)
|
||||
let existing2 = stack.fetchExisting(persistentID)
|
||||
XCTAssertNotNil(existing2)
|
||||
XCTAssertEqual(existing2!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing2!.persistentID(), persistentID)
|
||||
XCTAssertEqual(existing2!.managedObjectContext, stack.mainContext)
|
||||
|
||||
fetchExpectation.fulfill()
|
||||
@@ -136,6 +137,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchAllExisting() {
|
||||
|
||||
@@ -230,15 +232,15 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let persistentIDs = objects.map({ $0.persistentID() })
|
||||
let fetchExpectation = self.expectation(description: "fetch")
|
||||
var existing1 = [TestEntity1]()
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
existing1 = transaction.fetchExisting(objects)
|
||||
let existing1 = transaction.fetchExisting(persistentIDs)
|
||||
XCTAssertEqual(
|
||||
existing1.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
existing1.map { $0.persistentID() },
|
||||
persistentIDs
|
||||
)
|
||||
for object in existing1 {
|
||||
|
||||
@@ -254,10 +256,10 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
|
||||
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1)
|
||||
let existing2 = stack.fetchExisting(persistentIDs)
|
||||
XCTAssertEqual(
|
||||
existing2.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
existing2.map { $0.persistentID() },
|
||||
persistentIDs
|
||||
)
|
||||
for object in existing2 {
|
||||
|
||||
@@ -271,6 +273,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchOneFromDefaultConfiguration() {
|
||||
|
||||
@@ -404,6 +407,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchOneFromSingleConfiguration() {
|
||||
|
||||
@@ -581,6 +585,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchOneFromMultipleConfigurations() {
|
||||
|
||||
@@ -724,6 +729,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchAllFromDefaultConfiguration() {
|
||||
|
||||
@@ -912,6 +918,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchAllFromSingleConfiguration() {
|
||||
|
||||
@@ -1125,6 +1132,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchAllFromMultipleConfigurations() {
|
||||
|
||||
@@ -1306,6 +1314,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchCountFromDefaultConfiguration() {
|
||||
|
||||
@@ -1420,6 +1429,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchCountFromSingleConfiguration() {
|
||||
|
||||
@@ -1567,6 +1577,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchCountFromMultipleConfigurations() {
|
||||
|
||||
@@ -1677,6 +1688,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchOneFromDefaultConfiguration() {
|
||||
|
||||
@@ -1818,6 +1830,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchOneFromSingleConfiguration() {
|
||||
|
||||
@@ -2006,6 +2019,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchOneFromMultipleConfigurations() {
|
||||
|
||||
@@ -2157,6 +2171,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchAllFromDefaultConfiguration() {
|
||||
|
||||
@@ -2353,6 +2368,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchAllFromSingleConfiguration() {
|
||||
|
||||
@@ -2589,6 +2605,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchAllFromMultipleConfigurations() {
|
||||
|
||||
@@ -2790,6 +2807,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchCountFromDefaultConfiguration() {
|
||||
|
||||
@@ -2918,6 +2936,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchCountFromSingleConfiguration() {
|
||||
|
||||
@@ -3076,6 +3095,7 @@ final class FetchTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatTransactions_CanFetchCountFromMultipleConfigurations() {
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ final class FromTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForDefaultConfigurations() {
|
||||
|
||||
self.prepareStack { (dataStack) in
|
||||
@@ -106,6 +107,7 @@ final class FromTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForSingleConfigurations() {
|
||||
|
||||
self.prepareStack(configurations: ["Config1"]) { (dataStack) in
|
||||
@@ -212,6 +214,7 @@ final class FromTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForDefaultAndCustomConfigurations() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (dataStack) in
|
||||
@@ -316,6 +319,7 @@ final class FromTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForMultipleConfigurations() {
|
||||
|
||||
self.prepareStack(configurations: ["Config1", "Config2"]) { (dataStack) in
|
||||
|
||||
@@ -72,6 +72,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(Double(MAXFLOAT).cs_toQueryableNativeType(), NSNumber(value: Double(MAXFLOAT)))
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanSkipImport() {
|
||||
|
||||
@@ -107,6 +108,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanThrowError() {
|
||||
|
||||
@@ -160,6 +162,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanImportCorrectly() {
|
||||
|
||||
@@ -220,6 +223,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanSkipImport() {
|
||||
|
||||
@@ -275,6 +279,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanThrowError() {
|
||||
|
||||
@@ -339,6 +344,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanImportCorrectly() {
|
||||
|
||||
@@ -397,6 +403,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanSkipImport() {
|
||||
|
||||
@@ -466,6 +473,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_ImportsLastOfImportSourcesWithSameIDs() {
|
||||
|
||||
@@ -523,7 +531,8 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_MaintainsOrderOfInputSourceArray() {
|
||||
|
||||
@@ -585,6 +594,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanThrowError() {
|
||||
|
||||
@@ -680,7 +690,8 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanImportCorrectly() {
|
||||
|
||||
@@ -757,7 +768,8 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanSkipImport() {
|
||||
|
||||
@@ -815,7 +827,8 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanThrowError() {
|
||||
|
||||
@@ -977,6 +990,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanImportCorrectly() {
|
||||
|
||||
@@ -1065,7 +1079,7 @@ extension TestEntity1: ImportableUniqueObject {
|
||||
|
||||
// MARK: ImportableObject
|
||||
|
||||
typealias ImportSource = [String: Any]
|
||||
typealias ImportSource = [String: any Sendable]
|
||||
|
||||
static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import CoreStore
|
||||
|
||||
class ListObserverTests: BaseTestDataTestCase {
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveInsertNotifications() {
|
||||
|
||||
@@ -51,20 +52,23 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
XCTAssertFalse(monitor.hasObjects())
|
||||
XCTAssertTrue(monitor.objectsInAllSections().isEmpty)
|
||||
|
||||
var events = 0
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -72,51 +76,57 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
XCTAssertEqual(
|
||||
((note.userInfo as NSDictionary?) ?? [:]),
|
||||
[
|
||||
"sectionInfo": monitor.sectionInfo(at: 0),
|
||||
"sectionIndex": 0
|
||||
] as NSDictionary
|
||||
)
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 1)
|
||||
XCTAssertEqual(
|
||||
((note.userInfo as NSDictionary?) ?? [:]),
|
||||
[
|
||||
"sectionInfo": monitor.sectionInfo(at: 0),
|
||||
"sectionIndex": 0
|
||||
] as NSDictionary
|
||||
)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
handler: { [dateFormatter] (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:1")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-01T00:00:00Z")!)
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:1")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, dateFormatter.date(from: "2000-01-01T00:00:00Z")!)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -125,16 +135,19 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
asynchronous: { [dateFormatter] (transaction) -> Bool in
|
||||
|
||||
let object = transaction.create(Into<TestEntity1>())
|
||||
object.testBoolean = NSNumber(value: true)
|
||||
@@ -142,7 +155,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object.testDecimal = NSDecimalNumber(string: "1")
|
||||
object.testString = "nil:TestEntity1:1"
|
||||
object.testData = ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!
|
||||
object.testDate = self.dateFormatter.date(from: "2000-01-01T00:00:00Z")!
|
||||
object.testDate = dateFormatter.date(from: "2000-01-01T00:00:00Z")!
|
||||
|
||||
return transaction.hasChanges
|
||||
},
|
||||
@@ -160,6 +173,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveUpdateNotifications() {
|
||||
|
||||
@@ -182,72 +196,78 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(monitor.numberOfObjects(in: 0), 2)
|
||||
XCTAssertEqual(monitor.numberOfObjects(in: 1), 3)
|
||||
|
||||
var events = 0
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
handler: { [dateFormatter] (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
|
||||
switch object?.testEntityID {
|
||||
return events.withLock { events in
|
||||
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.section, 1)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
switch object?.testEntityID {
|
||||
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.section, 1)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -255,18 +275,21 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 3)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 3)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
asynchronous: { [dateFormatter] (transaction) -> Bool in
|
||||
|
||||
if let object = try transaction.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
@@ -276,7 +299,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object.testDecimal = NSDecimalNumber(string: "11")
|
||||
object.testString = "nil:TestEntity1:11"
|
||||
object.testData = ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!
|
||||
object.testDate = self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!
|
||||
object.testDate = dateFormatter.date(from: "2000-01-11T00:00:00Z")!
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -290,7 +313,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object.testDecimal = NSDecimalNumber(string: "22")
|
||||
object.testString = "nil:TestEntity1:22"
|
||||
object.testData = ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!
|
||||
object.testDate = self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!
|
||||
object.testDate = dateFormatter.date(from: "2000-01-22T00:00:00Z")!
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -312,6 +335,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveMoveNotifications() {
|
||||
|
||||
@@ -327,20 +351,23 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -348,32 +375,35 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["fromIndexPath", "toIndexPath", "object"]
|
||||
)
|
||||
|
||||
let fromIndexPath = userInfo?["fromIndexPath"] as? IndexPath
|
||||
XCTAssertEqual(fromIndexPath?.section, 0)
|
||||
XCTAssertEqual(fromIndexPath?.item, 0)
|
||||
|
||||
let toIndexPath = userInfo?["toIndexPath"] as? IndexPath
|
||||
XCTAssertEqual(toIndexPath?.section, 1)
|
||||
XCTAssertEqual(toIndexPath?.item, 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 1)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["fromIndexPath", "toIndexPath", "object"]
|
||||
)
|
||||
|
||||
let fromIndexPath = userInfo?["fromIndexPath"] as? IndexPath
|
||||
XCTAssertEqual(fromIndexPath?.section, 0)
|
||||
XCTAssertEqual(fromIndexPath?.item, 0)
|
||||
|
||||
let toIndexPath = userInfo?["toIndexPath"] as? IndexPath
|
||||
XCTAssertEqual(toIndexPath?.section, 1)
|
||||
XCTAssertEqual(toIndexPath?.item, 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -381,13 +411,16 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 2)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 2)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
@@ -420,6 +453,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveDeleteNotifications() {
|
||||
|
||||
@@ -435,20 +469,23 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -456,28 +493,31 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -485,27 +525,30 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 3)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["sectionInfo", "sectionIndex"]
|
||||
)
|
||||
|
||||
let sectionInfo = userInfo?["sectionInfo"] as? NSFetchedResultsSectionInfo
|
||||
XCTAssertNotNil(sectionInfo)
|
||||
XCTAssertEqual(sectionInfo?.name, "0")
|
||||
|
||||
let sectionIndex = userInfo?["sectionIndex"]
|
||||
XCTAssertEqual(sectionIndex as? NSNumber, NSNumber(value: 0))
|
||||
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 3)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["sectionInfo", "sectionIndex"]
|
||||
)
|
||||
|
||||
let sectionInfo = userInfo?["sectionInfo"] as? NSFetchedResultsSectionInfo
|
||||
XCTAssertNotNil(sectionInfo)
|
||||
XCTAssertEqual(sectionInfo?.name, "0")
|
||||
|
||||
let sectionIndex = userInfo?["sectionIndex"]
|
||||
XCTAssertEqual(sectionIndex as? NSNumber, NSNumber(value: 0))
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -513,13 +556,16 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 4)
|
||||
XCTAssertEqual((note.userInfo as NSDictionary?) ?? [:], NSDictionary())
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 4)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 4
|
||||
}
|
||||
return events == 4
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
@@ -551,7 +597,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
|
||||
// MARK: TestListObserver
|
||||
|
||||
class TestListObserver: ListSectionObserver {
|
||||
final class TestListObserver: ListSectionObserver {
|
||||
|
||||
// MARK: ListObserver
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import os
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
@@ -56,7 +55,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(monitor.object, object)
|
||||
XCTAssertFalse(monitor.isObjectDeleted)
|
||||
|
||||
let events: OSAllocatedUnfairLock<Int> = .init(initialState: 0)
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
let persistentID = object.persistentID()
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
|
||||
@@ -68,8 +68,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual(
|
||||
((note.userInfo as NSDictionary?) ?? [:]),
|
||||
["object": object] as NSDictionary
|
||||
(note.userInfo?["object"] as? TestEntity1)?.persistentID(),
|
||||
persistentID
|
||||
)
|
||||
defer {
|
||||
|
||||
@@ -89,16 +89,17 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
XCTAssertEqual(
|
||||
((note.userInfo as NSDictionary?) ?? [:]),
|
||||
[
|
||||
"object": object,
|
||||
"changedPersistentKeys": Set(
|
||||
[
|
||||
#keyPath(TestEntity1.testNumber),
|
||||
#keyPath(TestEntity1.testString)
|
||||
]
|
||||
)
|
||||
] as NSDictionary
|
||||
(note.userInfo?["object"] as? TestEntity1)?.persistentID(),
|
||||
persistentID
|
||||
)
|
||||
XCTAssertEqual(
|
||||
note.userInfo?["changedPersistentKeys"] as? Set<String>,
|
||||
Set(
|
||||
[
|
||||
#keyPath(TestEntity1.testNumber),
|
||||
#keyPath(TestEntity1.testString)
|
||||
]
|
||||
)
|
||||
)
|
||||
let object = note.userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 10))
|
||||
@@ -116,7 +117,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
guard let object = transaction.edit(object) else {
|
||||
guard let object = transaction.edit(persistentID) else {
|
||||
|
||||
XCTFail()
|
||||
try transaction.cancel()
|
||||
@@ -162,7 +163,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(monitor.object, object)
|
||||
XCTAssertFalse(monitor.isObjectDeleted)
|
||||
|
||||
let events: OSAllocatedUnfairLock<Int> = .init(initialState: 0)
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
let persistentID = object.persistentID()
|
||||
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "objectMonitor:didDeleteObject:"),
|
||||
@@ -174,8 +176,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual(
|
||||
((note.userInfo as NSDictionary?) ?? [:]),
|
||||
["object": object] as NSDictionary
|
||||
(note.userInfo?["object"] as? TestEntity1)?.persistentID(),
|
||||
persistentID
|
||||
)
|
||||
defer {
|
||||
|
||||
@@ -189,7 +191,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
guard let object = transaction.edit(object) else {
|
||||
guard let object = transaction.edit(persistentID) else {
|
||||
|
||||
XCTFail()
|
||||
try transaction.cancel()
|
||||
|
||||
@@ -63,10 +63,11 @@ class ObjectPublisherTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
let persistentID = object.persistentID()
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
guard let object = transaction.edit(object) else {
|
||||
guard let object = transaction.edit(persistentID) else {
|
||||
|
||||
XCTFail()
|
||||
try transaction.cancel()
|
||||
@@ -123,10 +124,11 @@ class ObjectPublisherTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
let persistentID = object.persistentID()
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
guard let object = transaction.edit(object) else {
|
||||
guard let object = transaction.edit(persistentID) else {
|
||||
|
||||
XCTFail()
|
||||
try transaction.cancel()
|
||||
|
||||
@@ -35,6 +35,7 @@ import CoreStore
|
||||
class QueryTests: BaseTestDataTestCase {
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryAttributeValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -219,6 +220,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryAverageValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -398,6 +400,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryCountValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -575,6 +578,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryMaximumValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -759,6 +763,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryMinimumValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -943,6 +948,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQuerySumValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -1121,6 +1127,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryObjectIDValue() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -1289,6 +1296,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryAttributes() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
@@ -1343,6 +1351,7 @@ class QueryTests: BaseTestDataTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatDataStacks_CanQueryAggregates() {
|
||||
|
||||
let configurations: [ModelConfiguration] = [nil]
|
||||
|
||||
@@ -27,6 +27,7 @@ import CoreData
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
@_spi(Internals)
|
||||
import CoreStore
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import CoreStore
|
||||
final class TransactionTests: BaseTestCase {
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatSynchronousTransactions_CanPerformCRUDs() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -151,6 +152,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatSynchronousTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
@@ -270,6 +272,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatSynchronousTransactions_CanDiscardUncommittedChanges() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -385,6 +388,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -398,19 +402,22 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
XCTAssertFalse(monitor.hasObjects())
|
||||
|
||||
var events = 0
|
||||
let events: Internals.Mutex<Int> = .init(0)
|
||||
_ = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertTrue(note.userInfo?.isEmpty != false)
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertTrue(note.userInfo?.isEmpty != false)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -418,29 +425,32 @@ final class TransactionTests: BaseTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:1")
|
||||
defer {
|
||||
return events.withLock { events in
|
||||
|
||||
events += 1
|
||||
XCTAssertEqual(events, 1)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.item, 0)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:1")
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
)
|
||||
_ = self.expectation(
|
||||
@@ -449,11 +459,14 @@ final class TransactionTests: BaseTestCase {
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertTrue(note.userInfo?.isEmpty != false)
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
return events.withLock { events in
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectation(description: "save")
|
||||
@@ -479,7 +492,7 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual(events.withLock({ $0 }), 0)
|
||||
XCTAssertEqual(monitor.numberOfObjects(), 0)
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
@@ -487,6 +500,7 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDs() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -626,6 +640,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
@@ -759,6 +774,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatAsynchronousTransactions_CanDiscardUncommittedChanges() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -900,6 +916,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatUnsafeTransactions_CanPerformCRUDs() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
@@ -995,6 +1012,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatUnsafeTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
@@ -1083,6 +1101,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
|
||||
@objc
|
||||
@MainActor
|
||||
dynamic func test_ThatUnsafeTransactions_CanRollbackChanges() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
@@ -37,18 +37,17 @@ final class TweakTests: XCTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatTweakClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
let tweak = Tweak {
|
||||
|
||||
$0.fetchOffset = 100
|
||||
$0.fetchLimit = 200
|
||||
$0.predicate = predicate
|
||||
$0.predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
}
|
||||
let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
tweak.applyToFetchRequest(request)
|
||||
XCTAssertEqual(request.fetchOffset, 100)
|
||||
XCTAssertEqual(request.fetchLimit, 200)
|
||||
XCTAssertNotNil(request.predicate)
|
||||
XCTAssertEqual(request.predicate, predicate)
|
||||
XCTAssertEqual(request.predicate, NSPredicate(format: "%K == %@", "key", "value"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user