mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-19 15:37:10 +01:00
importing unit tests
This commit is contained in:
@@ -70,7 +70,7 @@ class BaseTestCase: XCTestCase {
|
||||
CoreStore.logger = TestLogger(self.prepareLoggerExpectations(expectations))
|
||||
defer {
|
||||
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
CoreStore.logger = TestLogger([:])
|
||||
}
|
||||
return closure()
|
||||
@@ -93,6 +93,17 @@ class BaseTestCase: XCTestCase {
|
||||
return testExpectations
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
func checkExpectationsImmediately() {
|
||||
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
func waitAndCheckExpectations() {
|
||||
|
||||
self.waitForExpectationsWithTimeout(10, handler: nil)
|
||||
}
|
||||
|
||||
// MARK: XCTestCase
|
||||
|
||||
@@ -165,10 +176,9 @@ class TestLogger: CoreStoreLogger {
|
||||
self.fulfill(.AssertionFailure)
|
||||
}
|
||||
|
||||
@noreturn func fatalError(message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
||||
func abort(message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
||||
|
||||
self.fulfill(.FatalError)
|
||||
Swift.fatalError()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
//
|
||||
// CoreStoreTests.swift
|
||||
// CoreStoreTests
|
||||
//
|
||||
// Copyright © 2014 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
class CoreStoreTests: XCTestCase {
|
||||
|
||||
override func setUp() {
|
||||
|
||||
super.setUp()
|
||||
self.deleteStores()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
|
||||
self.deleteStores()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testExample() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
bundle: NSBundle(forClass: self.dynamicType)
|
||||
)
|
||||
CoreStore.defaultStack = stack
|
||||
XCTAssert(CoreStore.defaultStack === stack, "CoreStore.defaultStack === stack")
|
||||
|
||||
do {
|
||||
|
||||
try stack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "ConfigStore1.sqlite",
|
||||
configuration: "Config1",
|
||||
localStorageOptions: .RecreateStoreOnModelMismatch
|
||||
)
|
||||
)
|
||||
}
|
||||
catch let error as NSError {
|
||||
|
||||
XCTFail(error.description)
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
try stack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "ConfigStore2.sqlite",
|
||||
configuration: "Config2",
|
||||
localStorageOptions: .RecreateStoreOnModelMismatch
|
||||
)
|
||||
)
|
||||
}
|
||||
catch let error as NSError {
|
||||
|
||||
XCTFail(error.description)
|
||||
}
|
||||
|
||||
let unsafeTransaction = CoreStore.beginUnsafe()
|
||||
|
||||
let createExpectation = self.expectationWithDescription("Entity creation")
|
||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
|
||||
let obj1 = transaction.create(Into(TestEntity1))
|
||||
obj1.testEntityID = 1
|
||||
obj1.testString = "lololol"
|
||||
obj1.testNumber = 42
|
||||
obj1.testDate = NSDate()
|
||||
|
||||
let count = transaction.queryValue(
|
||||
From<TestEntity1>(),
|
||||
Select<Int>(.Count("testNumber"))
|
||||
)
|
||||
XCTAssertTrue(count == 0, "count == 0 (actual: \(count))") // counts only objects in store
|
||||
|
||||
let obj2 = transaction.create(Into<TestEntity2>())
|
||||
obj2.testEntityID = 2
|
||||
obj2.testString = "hahaha"
|
||||
obj2.testNumber = 100
|
||||
obj2.testDate = NSDate()
|
||||
|
||||
let obj3 = transaction.create(Into<TestEntity2>("Config2"))
|
||||
obj3.testEntityID = 3
|
||||
obj3.testString = "hahaha"
|
||||
obj3.testNumber = 90
|
||||
obj3.testDate = NSDate()
|
||||
|
||||
let obj4 = transaction.create(Into(TestEntity2.self, "Config2"))
|
||||
obj4.testEntityID = 5
|
||||
obj4.testString = "hohoho"
|
||||
obj4.testNumber = 80
|
||||
obj4.testDate = NSDate()
|
||||
|
||||
|
||||
transaction.beginSynchronous { (transaction) -> Void in
|
||||
|
||||
let obj4 = transaction.create(Into<TestEntity2>())
|
||||
obj4.testEntityID = 4
|
||||
obj4.testString = "hehehehe"
|
||||
obj4.testNumber = 80
|
||||
obj4.testDate = NSDate()
|
||||
|
||||
let objs4test = transaction.fetchOne(
|
||||
From<TestEntity2>("Config2"),
|
||||
Where("testEntityID", isEqualTo: 4),
|
||||
Tweak { (fetchRequest) -> Void in
|
||||
|
||||
fetchRequest.includesPendingChanges = true
|
||||
}
|
||||
)
|
||||
XCTAssertNotNil(objs4test, "objs4test != nil")
|
||||
|
||||
let objs5test = transaction.fetchOne(
|
||||
From(TestEntity2),
|
||||
Where("testEntityID", isEqualTo: 4),
|
||||
Tweak { (fetchRequest) -> Void in
|
||||
|
||||
fetchRequest.includesPendingChanges = false
|
||||
}
|
||||
)
|
||||
XCTAssertNil(objs5test, "objs5test == nil")
|
||||
|
||||
// Dont commit1
|
||||
}
|
||||
|
||||
transaction.commit { (result) -> Void in
|
||||
|
||||
let objs4test = CoreStore.fetchOne(
|
||||
From(TestEntity2),
|
||||
Where("testEntityID", isEqualTo: 4),
|
||||
Tweak { (fetchRequest) -> Void in
|
||||
|
||||
fetchRequest.includesPendingChanges = false
|
||||
}
|
||||
)
|
||||
XCTAssertNil(objs4test, "objs4test == nil")
|
||||
|
||||
let objs5test = unsafeTransaction.fetchCount(From(TestEntity2))
|
||||
XCTAssertTrue(objs5test == 3, "objs5test == 3")
|
||||
|
||||
XCTAssertTrue(NSThread.isMainThread(), "NSThread.isMainThread()")
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges, "hasChanges == true")
|
||||
createExpectation.fulfill()
|
||||
|
||||
case .Failure(let error):
|
||||
XCTFail("\(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let queryExpectation = self.expectationWithDescription("Query creation")
|
||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
|
||||
let obj1 = transaction.fetchOne(From(TestEntity1))
|
||||
XCTAssertNotNil(obj1, "obj1 != nil")
|
||||
|
||||
var orderBy = OrderBy(.Ascending("testEntityID"))
|
||||
orderBy += OrderBy(.Descending("testString"))
|
||||
let objs2 = transaction.fetchAll(
|
||||
From(TestEntity2),
|
||||
Where("testNumber", isEqualTo: 100) || Where("%K == %@", "testNumber", 90),
|
||||
orderBy,
|
||||
Tweak { (fetchRequest) -> Void in
|
||||
|
||||
fetchRequest.includesPendingChanges = true
|
||||
}
|
||||
)
|
||||
XCTAssertNotNil(objs2, "objs2 != nil")
|
||||
XCTAssertTrue(objs2?.count == 2, "objs2?.count == 2")
|
||||
|
||||
transaction.commit { (result) -> Void in
|
||||
|
||||
let counts = CoreStore.queryAttributes(
|
||||
From(TestEntity2),
|
||||
Select("testString", .Count("testString", As: "count")),
|
||||
GroupBy("testString")
|
||||
)
|
||||
|
||||
XCTAssertTrue(NSThread.isMainThread(), "NSThread.isMainThread()")
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertFalse(hasChanges, "hasChanges == false")
|
||||
queryExpectation.fulfill()
|
||||
|
||||
case .Failure(let error):
|
||||
XCTFail("\(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.waitForExpectationsWithTimeout(100, handler: nil)
|
||||
|
||||
let max1 = CoreStore.queryValue(
|
||||
From(TestEntity2),
|
||||
Select<Int>(.Maximum("testNumber"))
|
||||
)
|
||||
XCTAssertTrue(max1 == 100, "max == 100 (actual: \(max1))")
|
||||
|
||||
let max2 = CoreStore.queryValue(
|
||||
From(TestEntity2),
|
||||
Select<NSNumber>(.Maximum("testNumber")),
|
||||
Where("%K > %@", "testEntityID", 2)
|
||||
)
|
||||
XCTAssertTrue(max2 == 90, "max == 90 (actual: \(max2))")
|
||||
|
||||
CoreStore.beginSynchronous { (transaction) -> Void in
|
||||
|
||||
let numberOfDeletedObjects1 = transaction.deleteAll(From(TestEntity1))
|
||||
XCTAssertTrue(numberOfDeletedObjects1 == 1, "numberOfDeletedObjects1 == 1 (actual: \(numberOfDeletedObjects1))")
|
||||
|
||||
let numberOfDeletedObjects2 = transaction.deleteAll(
|
||||
From(TestEntity2),
|
||||
Where("%K > %@", "testEntityID", 2)
|
||||
)
|
||||
XCTAssertTrue(numberOfDeletedObjects2 == 2, "numberOfDeletedObjects2 == 2 (actual: \(numberOfDeletedObjects2))")
|
||||
|
||||
transaction.commitAndWait()
|
||||
}
|
||||
|
||||
CoreStore.beginSynchronous({ (transaction) -> Void in
|
||||
|
||||
if let obj = CoreStore.fetchOne(From(TestEntity2)) {
|
||||
|
||||
let oldID = obj.testEntityID
|
||||
obj.testEntityID = 0
|
||||
obj.testEntityID = oldID
|
||||
}
|
||||
|
||||
transaction.commitAndWait()
|
||||
})
|
||||
|
||||
let objs1 = CoreStore.fetchAll(From(TestEntity1))
|
||||
XCTAssertNotNil(objs1, "objs1 != nil")
|
||||
XCTAssertTrue(objs1?.count == 0, "objs1?.count == 0")
|
||||
|
||||
let objs2 = CoreStore.fetchAll(From(TestEntity2))
|
||||
XCTAssertNotNil(objs2, "objs2 != nil")
|
||||
XCTAssertTrue(objs2?.count == 1, "objs2?.count == 1")
|
||||
|
||||
let unsafeExpectation = self.expectationWithDescription("Query creation")
|
||||
|
||||
let obj5 = unsafeTransaction.create(Into<TestEntity1>("Config1"))
|
||||
obj5.testEntityID = 5
|
||||
obj5.testString = "hihihi"
|
||||
obj5.testNumber = 70
|
||||
obj5.testDate = NSDate()
|
||||
XCTAssert(unsafeTransaction === obj5.unsafeDataTransaction, "unsafeTransaction === obj5.unsafeDataTransaction")
|
||||
|
||||
unsafeTransaction.commit { (result) -> Void in
|
||||
|
||||
XCTAssertTrue(NSThread.isMainThread(), "NSThread.isMainThread()")
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges, "hasChanges == true")
|
||||
|
||||
CoreStore.beginSynchronous { (transaction) -> Void in
|
||||
|
||||
let obj5Copy1 = transaction.edit(obj5)
|
||||
XCTAssertTrue(obj5.objectID == obj5Copy1?.objectID, "obj5.objectID == obj5Copy1?.objectID")
|
||||
XCTAssertFalse(obj5 == obj5Copy1, "obj5 == obj5Copy1")
|
||||
XCTAssertNil(obj5Copy1?.unsafeDataTransaction)
|
||||
|
||||
let obj5Copy2 = transaction.edit(Into(TestEntity1), obj5.objectID)
|
||||
XCTAssertTrue(obj5.objectID == obj5Copy2?.objectID, "obj5.objectID == obj5Copy2?.objectID")
|
||||
XCTAssertFalse(obj5 == obj5Copy2, "obj5 == obj5Copy2")
|
||||
}
|
||||
|
||||
let count: Int? = CoreStore.queryValue(
|
||||
From(TestEntity1),
|
||||
Select(.Count("testNumber"))
|
||||
)
|
||||
XCTAssertTrue(count == 1, "count == 1 (actual: \(count))")
|
||||
|
||||
let obj6 = unsafeTransaction.create(Into<TestEntity1>())
|
||||
obj6.testEntityID = 6
|
||||
obj6.testString = "huehuehue"
|
||||
obj6.testNumber = 130
|
||||
obj6.testDate = NSDate()
|
||||
XCTAssert(unsafeTransaction === obj6.unsafeDataTransaction, "unsafeTransaction === obj6.unsafeDataTransaction")
|
||||
|
||||
unsafeTransaction.commit { (result) -> Void in
|
||||
|
||||
XCTAssertTrue(NSThread.isMainThread(), "NSThread.isMainThread()")
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges, "hasChanges == true")
|
||||
|
||||
let count = CoreStore.queryValue(
|
||||
From(TestEntity1),
|
||||
Select<Int>(.Count("testNumber"))
|
||||
)
|
||||
XCTAssertTrue(count == 2, "count == 2 (actual: \(count))")
|
||||
|
||||
|
||||
CoreStore.beginSynchronous { (transaction) -> Void in
|
||||
|
||||
let obj6 = transaction.edit(obj6)
|
||||
let obj5 = transaction.edit(obj5)
|
||||
transaction.delete(obj5, obj6)
|
||||
|
||||
transaction.commitAndWait()
|
||||
}
|
||||
|
||||
let count2 = CoreStore.queryValue(
|
||||
From(TestEntity1),
|
||||
Select<Int>(.Count("testNumber"))
|
||||
)
|
||||
XCTAssertTrue(count2 == 0, "count == 0 (actual: \(count2))")
|
||||
|
||||
unsafeExpectation.fulfill()
|
||||
|
||||
case .Failure(let error):
|
||||
XCTFail("\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
case .Failure(let error):
|
||||
XCTFail("\(error)")
|
||||
}
|
||||
}
|
||||
|
||||
self.waitForExpectationsWithTimeout(100, handler: nil)
|
||||
}
|
||||
|
||||
private func deleteStores() {
|
||||
|
||||
do {
|
||||
|
||||
try NSFileManager.defaultManager().removeItemAtURL(SQLiteStore.defaultRootDirectory)
|
||||
}
|
||||
catch _ { }
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import GCDKit
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
@@ -33,6 +34,195 @@ import CoreStore
|
||||
|
||||
final class FetchTests: BaseTestDataTestCase {
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchOneExisting() {
|
||||
|
||||
let configurations: [String?] = ["Config1"]
|
||||
self.prepareStack(configurations: configurations) { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||
|
||||
let from = From(TestEntity1)
|
||||
let fetchClauses: [FetchClause] = [
|
||||
OrderBy(.Ascending("testEntityID"))
|
||||
]
|
||||
let object = stack.fetchOne(from, fetchClauses)!
|
||||
do {
|
||||
|
||||
let existing = stack.fetchExisting(object)
|
||||
XCTAssertNotNil(existing)
|
||||
XCTAssertEqual(existing!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing!.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
do {
|
||||
|
||||
let transaction = stack.beginUnsafe()
|
||||
|
||||
let existing1 = transaction.fetchExisting(object)
|
||||
XCTAssertNotNil(existing1)
|
||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1!)
|
||||
XCTAssertNotNil(existing2)
|
||||
XCTAssertEqual(existing2!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing2!.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
do {
|
||||
|
||||
let fetchExpectation = self.expectationWithDescription("fetch")
|
||||
|
||||
var existing1: TestEntity1?
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
existing1 = transaction.fetchExisting(object)
|
||||
XCTAssertNotNil(existing1)
|
||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||
|
||||
fetchExpectation.fulfill()
|
||||
}
|
||||
let existing2 = stack.fetchExisting(existing1!)
|
||||
XCTAssertNotNil(existing2)
|
||||
XCTAssertEqual(existing2!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing2!.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
do {
|
||||
|
||||
let fetchExpectation = self.expectationWithDescription("fetch")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
let existing1 = transaction.fetchExisting(object)
|
||||
XCTAssertNotNil(existing1)
|
||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||
|
||||
GCDQueue.Main.async {
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1!)
|
||||
XCTAssertNotNil(existing2)
|
||||
XCTAssertEqual(existing2!.objectID, object.objectID)
|
||||
XCTAssertEqual(existing2!.managedObjectContext, stack.mainContext)
|
||||
|
||||
fetchExpectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchAllExisting() {
|
||||
|
||||
let configurations: [String?] = ["Config1"]
|
||||
self.prepareStack(configurations: configurations) { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||
|
||||
let from = From(TestEntity1)
|
||||
let fetchClauses: [FetchClause] = [
|
||||
OrderBy(.Ascending("testEntityID"))
|
||||
]
|
||||
let objects = stack.fetchAll(from, fetchClauses)!
|
||||
do {
|
||||
|
||||
let existing = stack.fetchExisting(objects)
|
||||
XCTAssertEqual(
|
||||
existing.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let transaction = stack.beginUnsafe()
|
||||
|
||||
let existing1 = transaction.fetchExisting(objects)
|
||||
XCTAssertEqual(
|
||||
existing1.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing1 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
||||
}
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1)
|
||||
XCTAssertEqual(
|
||||
existing2.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing2 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let fetchExpectation = self.expectationWithDescription("fetch")
|
||||
|
||||
var existing1 = [TestEntity1]()
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
existing1 = transaction.fetchExisting(objects)
|
||||
XCTAssertEqual(
|
||||
existing1.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing1 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
||||
}
|
||||
|
||||
fetchExpectation.fulfill()
|
||||
}
|
||||
let existing2 = stack.fetchExisting(existing1)
|
||||
XCTAssertEqual(
|
||||
existing2.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing2 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let fetchExpectation = self.expectationWithDescription("fetch")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
let existing1 = transaction.fetchExisting(objects)
|
||||
XCTAssertEqual(
|
||||
existing1.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing1 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
||||
}
|
||||
GCDQueue.Main.async {
|
||||
|
||||
let existing2 = stack.fetchExisting(existing1)
|
||||
XCTAssertEqual(
|
||||
existing2.map { $0.objectID },
|
||||
objects.map { $0.objectID }
|
||||
)
|
||||
for object in existing2 {
|
||||
|
||||
XCTAssertEqual(object.managedObjectContext, stack.mainContext)
|
||||
}
|
||||
fetchExpectation.fulfill()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatDataStacks_CanFetchOneFromDefaultConfiguration() {
|
||||
|
||||
|
||||
983
CoreStoreTests/ImportTests.swift
Normal file
983
CoreStoreTests/ImportTests.swift
Normal file
@@ -0,0 +1,983 @@
|
||||
//
|
||||
// ImportTests.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - ImportTests
|
||||
|
||||
class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanSkipImport() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let object = try transaction.importObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!,
|
||||
"skip_insert": ""
|
||||
]
|
||||
)
|
||||
XCTAssertNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 0)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanThrowError() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let _ = try transaction.importObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!,
|
||||
"throw_on_insert": ""
|
||||
]
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestInsertError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
let object = transaction.fetchOne(From(TestEntity1))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertNil(object?.testEntityID)
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
XCTAssertNil(object?.testNumber)
|
||||
XCTAssertNil(object?.testDecimal)
|
||||
XCTAssertNil(object?.testString)
|
||||
XCTAssertNil(object?.testData)
|
||||
XCTAssertNil(object?.testDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObject_CanImportCorrectly() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let object = try transaction.importObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!
|
||||
]
|
||||
)
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 1)
|
||||
XCTAssertNil(object?.testEntityID)
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:1")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!)
|
||||
|
||||
try transaction.importObject(
|
||||
object!,
|
||||
source: [
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 2),
|
||||
"testDecimal": NSDecimalNumber(string: "2"),
|
||||
"testString": "nil:TestEntity1:2",
|
||||
"testData": ("nil:TestEntity1:2" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-02T00:00:00Z")!
|
||||
]
|
||||
)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 1)
|
||||
XCTAssertNil(object?.testEntityID)
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 2))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "2"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:2")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:2" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-02T00:00:00Z")!)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanSkipImport() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!,
|
||||
"skip_insert": ""
|
||||
],
|
||||
[
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 2),
|
||||
"testDecimal": NSDecimalNumber(string: "2"),
|
||||
"testString": "nil:TestEntity1:2",
|
||||
"testData": ("nil:TestEntity1:2" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-02T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let objects = try transaction.importObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTAssertEqual(objects.count, 1)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
let object = objects[0]
|
||||
let dictionary = sourceArray[1]
|
||||
XCTAssertNil(object.testEntityID)
|
||||
XCTAssertEqual(object.testBoolean, dictionary["testBoolean"] as? NSNumber)
|
||||
XCTAssertEqual(object.testNumber, dictionary["testNumber"] as? NSNumber)
|
||||
XCTAssertEqual(object.testDecimal, dictionary["testDecimal"] as? NSDecimalNumber)
|
||||
XCTAssertEqual(object.testString, dictionary["testString"] as? String)
|
||||
XCTAssertEqual(object.testData, dictionary["testData"] as? NSData)
|
||||
XCTAssertEqual(object.testDate, dictionary["testDate"] as? NSDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanThrowError() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!,
|
||||
"throw_on_insert": ""
|
||||
],
|
||||
[
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 2),
|
||||
"testDecimal": NSDecimalNumber(string: "2"),
|
||||
"testString": "nil:TestEntity1:2",
|
||||
"testData": ("nil:TestEntity1:2" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-02T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let _ = try transaction.importObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestInsertError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
let object = transaction.fetchOne(From(TestEntity1))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertNil(object?.testEntityID)
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
XCTAssertNil(object?.testNumber)
|
||||
XCTAssertNil(object?.testDecimal)
|
||||
XCTAssertNil(object?.testString)
|
||||
XCTAssertNil(object?.testData)
|
||||
XCTAssertNil(object?.testDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportObjects_CanImportCorrectly() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 1),
|
||||
"testDecimal": NSDecimalNumber(string: "1"),
|
||||
"testString": "nil:TestEntity1:1",
|
||||
"testData": ("nil:TestEntity1:1" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-01T00:00:00Z")!
|
||||
],
|
||||
[
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 2),
|
||||
"testDecimal": NSDecimalNumber(string: "2"),
|
||||
"testString": "nil:TestEntity1:2",
|
||||
"testData": ("nil:TestEntity1:2" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-02T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let objects = try transaction.importObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTAssertEqual(objects.count, sourceArray.count)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 2)
|
||||
|
||||
for i in 0 ..< sourceArray.count {
|
||||
|
||||
let object = objects[i]
|
||||
let dictionary = sourceArray[i]
|
||||
|
||||
XCTAssertNil(object.testEntityID)
|
||||
XCTAssertEqual(object.testBoolean, dictionary["testBoolean"] as? NSNumber)
|
||||
XCTAssertEqual(object.testNumber, dictionary["testNumber"] as? NSNumber)
|
||||
XCTAssertEqual(object.testDecimal, dictionary["testDecimal"] as? NSDecimalNumber)
|
||||
XCTAssertEqual(object.testString, dictionary["testString"] as? String)
|
||||
XCTAssertEqual(object.testData, dictionary["testData"] as? NSData)
|
||||
XCTAssertEqual(object.testDate, dictionary["testDate"] as? NSDate)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanSkipImport() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let object = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"skip_insert": ""
|
||||
]
|
||||
)
|
||||
XCTAssertNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 5)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
do {
|
||||
|
||||
let object = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 105),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"skip_update": ""
|
||||
]
|
||||
)
|
||||
XCTAssertNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 5)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From(TestEntity1), Where("testEntityID", isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
let existingObject = existingObjects?[0]
|
||||
XCTAssertEqual(existingObject?.testEntityID, NSNumber(integer: 105))
|
||||
XCTAssertEqual(existingObject?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(existingObject?.testNumber, NSNumber(integer: 5))
|
||||
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
|
||||
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
|
||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.dateFromString("2000-01-05T00:00:00Z")!)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanThrowError() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let _ = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"throw_on_insert": ""
|
||||
]
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestInsertError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
|
||||
let object = transaction.fetchOne(From(TestEntity1), Where("testEntityID", isEqualTo: 106))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 106))
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
XCTAssertNil(object?.testNumber)
|
||||
XCTAssertNil(object?.testDecimal)
|
||||
XCTAssertNil(object?.testString)
|
||||
XCTAssertNil(object?.testData)
|
||||
XCTAssertNil(object?.testDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
}
|
||||
do {
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let _ = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 105),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"throw_on_update": ""
|
||||
]
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestUpdateError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From(TestEntity1), Where("testEntityID", isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
let existingObject = existingObjects?[0]
|
||||
XCTAssertNotNil(existingObject)
|
||||
XCTAssertEqual(existingObject?.testEntityID, NSNumber(integer: 105))
|
||||
XCTAssertEqual(existingObject?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(existingObject?.testNumber, NSNumber(integer: 5))
|
||||
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
|
||||
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
|
||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.dateFromString("2000-01-05T00:00:00Z")!)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObject_CanImportCorrectly() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let object = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!
|
||||
]
|
||||
)
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 106))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 6))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "6"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:6")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
do {
|
||||
|
||||
let object = try transaction.importUniqueObject(
|
||||
Into(TestEntity1),
|
||||
source: [
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 7),
|
||||
"testDecimal": NSDecimalNumber(string: "7"),
|
||||
"testString": "nil:TestEntity1:7",
|
||||
"testData": ("nil:TestEntity1:7" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-07T00:00:00Z")!,
|
||||
]
|
||||
)
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 106))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 7))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "7"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:7")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-07T00:00:00Z")!)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From(TestEntity1), Where("testEntityID", isEqualTo: 106))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
let existingObject = existingObjects?[0]
|
||||
XCTAssertEqual(existingObject, object)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanSkipImport() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"skip_insert": ""
|
||||
],
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 107),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 7),
|
||||
"testDecimal": NSDecimalNumber(string: "7"),
|
||||
"testString": "nil:TestEntity1:7",
|
||||
"testData": ("nil:TestEntity1:7" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-07T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let objects = try transaction.importUniqueObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTAssertEqual(objects.count, 1)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
|
||||
let object = objects[0]
|
||||
let dictionary = sourceArray[1]
|
||||
XCTAssertEqual(object.testEntityID, dictionary["testEntityID"] as? NSNumber)
|
||||
XCTAssertEqual(object.testBoolean, dictionary["testBoolean"] as? NSNumber)
|
||||
XCTAssertEqual(object.testNumber, dictionary["testNumber"] as? NSNumber)
|
||||
XCTAssertEqual(object.testDecimal, dictionary["testDecimal"] as? NSDecimalNumber)
|
||||
XCTAssertEqual(object.testString, dictionary["testString"] as? String)
|
||||
XCTAssertEqual(object.testData, dictionary["testData"] as? NSData)
|
||||
XCTAssertEqual(object.testDate, dictionary["testDate"] as? NSDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanThrowError() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"throw_on_id": ""
|
||||
],
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 107),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 7),
|
||||
"testDecimal": NSDecimalNumber(string: "7"),
|
||||
"testString": "nil:TestEntity1:7",
|
||||
"testData": ("nil:TestEntity1:7" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-07T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let _ = try transaction.importUniqueObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestIDError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 5)
|
||||
|
||||
XCTAssertNil(transaction.fetchOne(From(TestEntity1), Where("testEntityID", isEqualTo: 106)))
|
||||
XCTAssertNil(transaction.fetchOne(From(TestEntity1), Where("testEntityID", isEqualTo: 107)))
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
transaction.context.reset()
|
||||
}
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: true),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"throw_on_insert": ""
|
||||
],
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 107),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 7),
|
||||
"testDecimal": NSDecimalNumber(string: "7"),
|
||||
"testString": "nil:TestEntity1:7",
|
||||
"testData": ("nil:TestEntity1:7" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-07T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let _ = try transaction.importUniqueObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestInsertError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 7)
|
||||
|
||||
let object = transaction.fetchOne(From(TestEntity1), Where("testEntityID", isEqualTo: 106))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 106))
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
XCTAssertNil(object?.testNumber)
|
||||
XCTAssertNil(object?.testDecimal)
|
||||
XCTAssertNil(object?.testString)
|
||||
XCTAssertNil(object?.testData)
|
||||
XCTAssertNil(object?.testDate)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
transaction.context.reset()
|
||||
}
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let errorExpectation = self.expectationWithDescription("error")
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 105),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!,
|
||||
"throw_on_update": ""
|
||||
]
|
||||
]
|
||||
let _ = try transaction.importUniqueObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTFail()
|
||||
}
|
||||
catch _ as TestUpdateError {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 5)
|
||||
|
||||
let object = transaction.fetchOne(From(TestEntity1), Where("testEntityID", isEqualTo: 105))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 105))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 5))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "5"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:5")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-05T00:00:00Z")!)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From(TestEntity1), Where("testEntityID", isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
let existingObject = existingObjects?[0]
|
||||
XCTAssertEqual(existingObject, object)
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatImportUniqueObjects_CanImportCorrectly() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
do {
|
||||
|
||||
let sourceArray: [TestEntity1.ImportSource] = [
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 105),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 15),
|
||||
"testDecimal": NSDecimalNumber(string: "15"),
|
||||
"testString": "nil:TestEntity1:15",
|
||||
"testData": ("nil:TestEntity1:15" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-15T00:00:00Z")!
|
||||
],
|
||||
[
|
||||
"testEntityID": NSNumber(integer: 106),
|
||||
"testBoolean": NSNumber(bool: false),
|
||||
"testNumber": NSNumber(integer: 6),
|
||||
"testDecimal": NSDecimalNumber(string: "6"),
|
||||
"testString": "nil:TestEntity1:6",
|
||||
"testData": ("nil:TestEntity1:6" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!,
|
||||
"testDate": self.dateFormatter.dateFromString("2000-01-06T00:00:00Z")!
|
||||
]
|
||||
]
|
||||
let objects = try transaction.importUniqueObjects(
|
||||
Into(TestEntity1),
|
||||
sourceArray: sourceArray
|
||||
)
|
||||
XCTAssertEqual(objects.count, sourceArray.count)
|
||||
XCTAssertEqual(transaction.fetchCount(From(TestEntity1)), 6)
|
||||
for i in 0 ..< sourceArray.count {
|
||||
|
||||
let object = objects[i]
|
||||
let dictionary = sourceArray[i]
|
||||
|
||||
XCTAssertEqual(object.testEntityID, dictionary["testEntityID"] as? NSNumber)
|
||||
XCTAssertEqual(object.testBoolean, dictionary["testBoolean"] as? NSNumber)
|
||||
XCTAssertEqual(object.testNumber, dictionary["testNumber"] as? NSNumber)
|
||||
XCTAssertEqual(object.testDecimal, dictionary["testDecimal"] as? NSDecimalNumber)
|
||||
XCTAssertEqual(object.testString, dictionary["testString"] as? String)
|
||||
XCTAssertEqual(object.testData, dictionary["testData"] as? NSData)
|
||||
XCTAssertEqual(object.testDate, dictionary["testDate"] as? NSDate)
|
||||
}
|
||||
let existingObjects = transaction.fetchAll(From(TestEntity1), Where("testEntityID", isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
let existingObject = existingObjects?[0]
|
||||
XCTAssertEqual(existingObject, objects[0])
|
||||
}
|
||||
catch {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.context.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - TestInsertError
|
||||
|
||||
private struct TestInsertError: ErrorType {}
|
||||
|
||||
|
||||
// MARK: - TestUpdateError
|
||||
|
||||
private struct TestUpdateError: ErrorType {}
|
||||
|
||||
|
||||
// MARK: - TestIDError
|
||||
|
||||
private struct TestIDError: ErrorType {}
|
||||
|
||||
|
||||
// MARK: - TestEntity1
|
||||
|
||||
extension TestEntity1: ImportableUniqueObject {
|
||||
|
||||
// MARK: ImportableObject
|
||||
|
||||
typealias ImportSource = [String: AnyObject]
|
||||
|
||||
static func shouldInsertFromImportSource(source: [String: AnyObject], inTransaction transaction: BaseDataTransaction) -> Bool {
|
||||
|
||||
return source["skip_insert"] == nil
|
||||
}
|
||||
|
||||
func didInsertFromImportSource(source: [String: AnyObject], inTransaction transaction: BaseDataTransaction) throws {
|
||||
|
||||
if let _ = source["throw_on_insert"] {
|
||||
|
||||
throw TestInsertError()
|
||||
}
|
||||
self.testBoolean = source["testBoolean"] as? NSNumber
|
||||
self.testNumber = source["testNumber"] as? NSNumber
|
||||
self.testDecimal = source["testDecimal"] as? NSDecimalNumber
|
||||
self.testString = source["testString"] as? String
|
||||
self.testData = source["testData"] as? NSData
|
||||
self.testDate = source["testDate"] as? NSDate
|
||||
self.testNil = nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: ImportableUniqueObject
|
||||
|
||||
typealias UniqueIDType = NSNumber
|
||||
|
||||
static var uniqueIDKeyPath: String {
|
||||
|
||||
return "testEntityID"
|
||||
}
|
||||
|
||||
var uniqueIDValue: NSNumber {
|
||||
|
||||
get {
|
||||
|
||||
guard let ID = self.testEntityID else {
|
||||
|
||||
XCTFail()
|
||||
return 0
|
||||
}
|
||||
return ID
|
||||
}
|
||||
set {
|
||||
|
||||
self.testEntityID = newValue
|
||||
}
|
||||
}
|
||||
|
||||
static func shouldUpdateFromImportSource(source: [String: AnyObject], inTransaction transaction: BaseDataTransaction) -> Bool {
|
||||
|
||||
return source["skip_update"] == nil
|
||||
}
|
||||
|
||||
static func uniqueIDFromImportSource(source: [String: AnyObject], inTransaction transaction: BaseDataTransaction) throws -> NSNumber? {
|
||||
|
||||
if let _ = source["throw_on_id"] {
|
||||
|
||||
throw TestIDError()
|
||||
}
|
||||
return source["testEntityID"] as? NSNumber
|
||||
}
|
||||
|
||||
func updateFromImportSource(source: [String: AnyObject], inTransaction transaction: BaseDataTransaction) throws {
|
||||
|
||||
if let _ = source["throw_on_update"] {
|
||||
|
||||
throw TestUpdateError()
|
||||
}
|
||||
self.testBoolean = source["testBoolean"] as? NSNumber
|
||||
self.testNumber = source["testNumber"] as? NSNumber
|
||||
self.testDecimal = source["testDecimal"] as? NSDecimalNumber
|
||||
self.testString = source["testString"] as? String
|
||||
self.testData = source["testData"] as? NSData
|
||||
self.testDate = source["testDate"] as? NSDate
|
||||
self.testNil = nil
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,20 @@
|
||||
<attribute name="testBoolean" optional="YES" attributeType="Boolean" syncable="YES"/>
|
||||
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
|
||||
<attribute name="testDate" optional="YES" attributeType="Date" syncable="YES"/>
|
||||
<attribute name="testDecimal" optional="YES" attributeType="Decimal" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="testEntityID" attributeType="Integer 64" syncable="YES"/>
|
||||
<attribute name="testDecimal" optional="YES" attributeType="Decimal" syncable="YES"/>
|
||||
<attribute name="testEntityID" optional="YES" attributeType="Integer 64" syncable="YES"/>
|
||||
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" syncable="YES"/>
|
||||
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES">
|
||||
<attribute name="testBoolean" optional="YES" attributeType="Boolean" syncable="YES"/>
|
||||
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
|
||||
<attribute name="testDate" optional="YES" attributeType="Date" syncable="YES"/>
|
||||
<attribute name="testDecimal" optional="YES" attributeType="Decimal" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="testEntityID" attributeType="Integer 64" syncable="YES"/>
|
||||
<attribute name="testDecimal" optional="YES" attributeType="Decimal" syncable="YES"/>
|
||||
<attribute name="testEntityID" optional="YES" attributeType="Integer 64" syncable="YES"/>
|
||||
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" syncable="YES"/>
|
||||
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<configuration name="Config1">
|
||||
|
||||
37
CoreStoreTests/ObjectObserverTests.swift
Normal file
37
CoreStoreTests/ObjectObserverTests.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// ObjectObserverTests.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - ObjectObserverTests
|
||||
|
||||
class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
|
||||
}
|
||||
@@ -24,11 +24,10 @@
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import GCDKit
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
@testable
|
||||
import GCDKit
|
||||
|
||||
|
||||
//MARK: - TransactionTests
|
||||
@@ -62,7 +61,7 @@ final class TransactionTests: BaseTestCase {
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
@@ -97,7 +96,7 @@ final class TransactionTests: BaseTestCase {
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
@@ -126,7 +125,7 @@ final class TransactionTests: BaseTestCase {
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 0)
|
||||
|
||||
@@ -136,6 +135,107 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatSynchronousTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
|
||||
let testDate = NSDate()
|
||||
do {
|
||||
|
||||
let createExpectation = self.expectationWithDescription("create")
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let object = transaction.create(Into<TestEntity1>("Config1"))
|
||||
object.testEntityID = NSNumber(integer: 1)
|
||||
object.testString = "string1"
|
||||
object.testNumber = 100
|
||||
object.testDate = testDate
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
createExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1")
|
||||
XCTAssertEqual(object?.testNumber, 100)
|
||||
XCTAssertEqual(object?.testDate, testDate)
|
||||
}
|
||||
do {
|
||||
|
||||
let updateExpectation = self.expectationWithDescription("update")
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||
|
||||
XCTFail()
|
||||
return
|
||||
}
|
||||
object.testString = "string1_edit"
|
||||
object.testNumber = 200
|
||||
object.testDate = NSDate.distantFuture()
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
updateExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1_edit")
|
||||
XCTAssertEqual(object?.testNumber, 200)
|
||||
XCTAssertEqual(object?.testDate, NSDate.distantFuture())
|
||||
}
|
||||
do {
|
||||
|
||||
let deleteExpectation = self.expectationWithDescription("delete")
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||
transaction.delete(object)
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
deleteExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatSynchronousTransactions_CanDiscardUncommittedChanges() {
|
||||
|
||||
@@ -156,7 +256,7 @@ final class TransactionTests: BaseTestCase {
|
||||
createDiscardExpectation.fulfill()
|
||||
self.expectLogger(loggerExpectations)
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 0)
|
||||
|
||||
@@ -184,7 +284,7 @@ final class TransactionTests: BaseTestCase {
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
}
|
||||
do {
|
||||
|
||||
@@ -204,7 +304,7 @@ final class TransactionTests: BaseTestCase {
|
||||
updateDiscardExpectation.fulfill()
|
||||
self.expectLogger(loggerExpectations)
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
@@ -231,7 +331,7 @@ final class TransactionTests: BaseTestCase {
|
||||
deleteDiscardExpectation.fulfill()
|
||||
self.expectLogger(loggerExpectations)
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(0, handler: nil)
|
||||
self.checkExpectationsImmediately()
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From(TestEntity1)), 1)
|
||||
|
||||
@@ -350,7 +450,116 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(NSTimeInterval(Int8.max), handler: nil)
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
|
||||
let testDate = NSDate()
|
||||
do {
|
||||
|
||||
let createExpectation = self.expectationWithDescription("create")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
let object = transaction.create(Into<TestEntity1>("Config1"))
|
||||
object.testEntityID = NSNumber(integer: 1)
|
||||
object.testString = "string1"
|
||||
object.testNumber = 100
|
||||
object.testDate = testDate
|
||||
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1")
|
||||
XCTAssertEqual(object?.testNumber, 100)
|
||||
XCTAssertEqual(object?.testDate, testDate)
|
||||
createExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let updateExpectation = self.expectationWithDescription("update")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||
|
||||
XCTFail()
|
||||
return
|
||||
}
|
||||
object.testString = "string1_edit"
|
||||
object.testNumber = 200
|
||||
object.testDate = NSDate.distantFuture()
|
||||
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1_edit")
|
||||
XCTAssertEqual(object?.testNumber, 200)
|
||||
XCTAssertEqual(object?.testDate, NSDate.distantFuture())
|
||||
updateExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let deleteExpectation = self.expectationWithDescription("delete")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||
transaction.delete(object)
|
||||
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
deleteExpectation.fulfill()
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
|
||||
@objc
|
||||
@@ -458,7 +667,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitForExpectationsWithTimeout(NSTimeInterval(Int8.max), handler: nil)
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
|
||||
@objc
|
||||
@@ -542,6 +751,89 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatUnsafeTransactions_CanPerformCRUDsInCorrectConfiguration() {
|
||||
|
||||
self.prepareStack(configurations: [nil, "Config1"]) { (stack) in
|
||||
|
||||
let transaction = stack.beginUnsafe()
|
||||
|
||||
let testDate = NSDate()
|
||||
do {
|
||||
|
||||
let object = transaction.create(Into<TestEntity1>("Config1"))
|
||||
object.testEntityID = NSNumber(integer: 1)
|
||||
object.testString = "string1"
|
||||
object.testNumber = 100
|
||||
object.testDate = testDate
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1")
|
||||
XCTAssertEqual(object?.testNumber, 100)
|
||||
XCTAssertEqual(object?.testDate, testDate)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||
|
||||
XCTFail()
|
||||
return
|
||||
}
|
||||
object.testString = "string1_edit"
|
||||
object.testNumber = 200
|
||||
object.testDate = NSDate.distantFuture()
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testString, "string1_edit")
|
||||
XCTAssertEqual(object?.testNumber, 200)
|
||||
XCTAssertEqual(object?.testDate, NSDate.distantFuture())
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||
transaction.delete(object)
|
||||
|
||||
switch transaction.commitAndWait() {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatUnsafeTransactions_CanRollbackChanges() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user