WIP: objc utilities

This commit is contained in:
John Rommel Estropia
2016-06-19 02:40:25 +09:00
parent 3d5c4f8121
commit e5a199489c
19 changed files with 913 additions and 177 deletions

View File

@@ -28,7 +28,7 @@ class BaseTestDataTestCase: BaseTestCase {
}()
@nonobjc
func prepareTestDataForStack(stack: DataStack, configurations: [String?]) {
func prepareTestDataForStack(stack: DataStack, configurations: [String?] = [nil]) {
stack.beginSynchronous { (transaction) in

View File

@@ -24,14 +24,17 @@
//
#import "BridgingTests.h"
#import <CoreStore/CoreStore.h>
#import <CoreStore/CoreStore-Swift.h>
#import "CoreStoreTests-Swift.h"
@import CoreData;
// MARK: - BridgingTests
@implementation BridgingTests
- (void)testFlags {
- (void)test_ThatFlags_HaveCorrectValues {
XCTAssertEqual(CSLocalStorageOptionsNone, 0);
XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1);
@@ -39,7 +42,48 @@
XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4);
}
- (void)testDataStack {
- (void)test_ThatFromClauses_BridgeCorrectly {
{
CSFrom *from = From([TestEntity1 class]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
XCTAssertNil(from.configurations);
}
{
CSFrom *from = From([TestEntity1 class], @[[NSNull null], @"Config2"]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null], @"Config2"];
XCTAssertEqualObjects(from.configurations, configurations);
}
}
- (void)test_ThatWhereClauses_BridgeCorrectly {
{
CSWhere *where = Where(@"%K == %@", @"key", @"value");
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = Where(YES);
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = Where([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
}
- (void)test_ThatGroupByClauses_BridgeCorrectly {
CSGroupBy *groupBy = GroupBy(@[@"key"]);
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
}
- (void)test_ThatDataStacks_BridgeCorrectly {
CSDataStack *dataStack = [[CSDataStack alloc]
initWithModelName:@"Model"

View File

@@ -40,45 +40,35 @@ final class FromTests: BaseTestCase {
let from = From()
XCTAssert(from.entityClass === NSManagedObject.self)
XCTAssertNil(from.dumpInfo)
XCTAssertNil(from.configurations)
}
do {
let from = From<TestEntity1>()
XCTAssert(from.entityClass === TestEntity1.self)
XCTAssertNil(from.dumpInfo)
XCTAssertNil(from.configurations)
}
do {
let from = From<TestEntity1>("Config1")
XCTAssert(from.entityClass === TestEntity1.self)
let dumpInfo = from.dumpInfo
XCTAssertEqual(dumpInfo?.key, "configurations")
let configurations = dumpInfo?.value as! [String?]
XCTAssertEqual(configurations.count, 1)
XCTAssertEqual(configurations[0], "Config1")
XCTAssertEqual(from.configurations?.count, 1)
XCTAssertEqual(from.configurations?[0], "Config1")
}
do {
let from = From<TestEntity1>(nil, "Config1")
XCTAssert(from.entityClass === TestEntity1.self)
let dumpInfo = from.dumpInfo
XCTAssertEqual(dumpInfo?.key, "configurations")
let configurations = dumpInfo?.value as! [String?]
XCTAssertEqual(configurations.count, 2)
XCTAssertEqual(configurations[0], nil)
XCTAssertEqual(configurations[1], "Config1")
XCTAssertEqual(from.configurations?.count, 2)
XCTAssertEqual(from.configurations?[0], nil)
XCTAssertEqual(from.configurations?[1], "Config1")
}
}
@objc
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForDefaultConfigurations() {
self.prepareStack(configurations: [nil]) { (dataStack) in
self.prepareStack { (dataStack) in
do {

View File

@@ -349,7 +349,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in
@@ -419,7 +419,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in
@@ -519,7 +519,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in
@@ -598,7 +598,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in
@@ -656,7 +656,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in
@@ -818,7 +818,7 @@ class ImportTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
stack.beginSynchronous { (transaction) in

View File

@@ -44,12 +44,12 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList(
From(TestEntity1),
SectionBy("testBoolean"),
OrderBy(.Ascending("testEntityID"))
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
)
monitor.addObserver(observer)
XCTAssertFalse(monitor.hasSections())
XCTAssertFalse(monitor.hasObjects())
XCTAssertFalse(monitor.hasObjectsInSection(0))
XCTAssertTrue(monitor.objectsInAllSections().isEmpty)
var events = 0
@@ -59,6 +59,7 @@ class ListObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
@@ -72,6 +73,7 @@ class ListObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 1)
XCTAssertEqual(
(note.userInfo ?? [:]),
[
@@ -91,11 +93,20 @@ class ListObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
let indexPath = note.userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(events, 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.row, 0)
let object = note.userInfo?["object"] as? TestEntity1
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
XCTAssertEqual(object?.testNumber, NSNumber(integer: 1))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
@@ -149,6 +160,397 @@ class ListObserverTests: BaseTestDataTestCase {
self.waitAndCheckExpectations()
}
}
@objc
dynamic func test_ThatListObservers_CanReceiveUpdateNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = TestListObserver()
let monitor = stack.monitorSectionedList(
From(TestEntity1),
SectionBy("testBoolean"),
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
)
monitor.addObserver(observer)
XCTAssertTrue(monitor.hasSections())
XCTAssertEqual(monitor.numberOfSections(), 2)
XCTAssertTrue(monitor.hasObjects())
XCTAssertTrue(monitor.hasObjectsInSection(0))
XCTAssertEqual(monitor.numberOfObjectsInSection(0), 2)
XCTAssertEqual(monitor.numberOfObjectsInSection(1), 3)
var events = 0
let willChangeExpectation = self.expectationForNotification(
"listMonitorWillChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 0
}
)
for _ in 1 ... 2 {
let didUpdateObjectExpectation = self.expectationForNotification(
"listMonitor:didUpdateObject:atIndexPath:",
object: observer,
handler: { (note) -> Bool in
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
let object = userInfo?["object"] as? TestEntity1
switch object?.testEntityID {
case NSNumber(integer: 101)?:
XCTAssertEqual(indexPath?.section, 1)
XCTAssertEqual(indexPath?.row, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
XCTAssertEqual(object?.testNumber, NSNumber(integer: 11))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-11T00:00:00Z")!)
case NSNumber(integer: 102)?:
XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.row, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(bool: false))
XCTAssertEqual(object?.testNumber, NSNumber(integer: 22))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-22T00:00:00Z")!)
default:
XCTFail()
}
defer {
events += 1
}
return events == 1 || events == 2
}
)
}
let didChangeExpectation = self.expectationForNotification(
"listMonitorDidChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 3)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 3
}
)
let saveExpectation = self.expectationWithDescription("save")
stack.beginAsynchronous { (transaction) in
if let object = transaction.fetchOne(
From(TestEntity1),
Where("testEntityID", isEqualTo: 101)) {
object.testNumber = NSNumber(integer: 11)
object.testDecimal = NSDecimalNumber(string: "11")
object.testString = "nil:TestEntity1:11"
object.testData = ("nil:TestEntity1:11" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
object.testDate = self.dateFormatter.dateFromString("2000-01-11T00:00:00Z")!
}
else {
XCTFail()
}
if let object = transaction.fetchOne(
From(TestEntity1),
Where("testEntityID", isEqualTo: 102)) {
object.testNumber = NSNumber(integer: 22)
object.testDecimal = NSDecimalNumber(string: "22")
object.testString = "nil:TestEntity1:22"
object.testData = ("nil:TestEntity1:22" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
object.testDate = self.dateFormatter.dateFromString("2000-01-22T00:00:00Z")!
}
else {
XCTFail()
}
transaction.commit { (result) in
switch result {
case .Success(let hasChanges):
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
case .Failure:
XCTFail()
}
}
}
self.waitAndCheckExpectations()
}
}
@objc
dynamic func test_ThatListObservers_CanReceiveMoveNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = TestListObserver()
let monitor = stack.monitorSectionedList(
From(TestEntity1),
SectionBy("testBoolean"),
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
)
monitor.addObserver(observer)
var events = 0
let willChangeExpectation = self.expectationForNotification(
"listMonitorWillChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 0
}
)
let didMoveObjectExpectation = self.expectationForNotification(
"listMonitor:didMoveObject:fromIndexPath:toIndexPath:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 1)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
["fromIndexPath", "toIndexPath", "object"]
)
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
XCTAssertEqual(fromIndexPath?.section, 0)
XCTAssertEqual(fromIndexPath?.row, 0)
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
XCTAssertEqual(toIndexPath?.section, 1)
XCTAssertEqual(toIndexPath?.row, 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 102))
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
defer {
events += 1
}
return events == 1
}
)
let didChangeExpectation = self.expectationForNotification(
"listMonitorDidChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 2)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 2
}
)
let saveExpectation = self.expectationWithDescription("save")
stack.beginAsynchronous { (transaction) in
if let object = transaction.fetchOne(
From(TestEntity1),
Where("testEntityID", isEqualTo: 102)) {
object.testBoolean = NSNumber(bool: true)
}
else {
XCTFail()
}
transaction.commit { (result) in
switch result {
case .Success(let hasChanges):
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
case .Failure:
XCTFail()
}
}
}
self.waitAndCheckExpectations()
}
}
@objc
dynamic func test_ThatListObservers_CanReceiveDeleteNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = TestListObserver()
let monitor = stack.monitorSectionedList(
From(TestEntity1),
SectionBy("testBoolean"),
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
)
monitor.addObserver(observer)
var events = 0
let willChangeExpectation = self.expectationForNotification(
"listMonitorWillChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 0
}
)
for _ in 1 ... 2 {
let didUpdateObjectExpectation = self.expectationForNotification(
"listMonitor:didDeleteObject:fromIndexPath:",
object: observer,
handler: { (note) -> Bool in
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.row == 0 || indexPath?.row == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.deleted, true)
defer {
events += 1
}
return events == 1 || events == 2
}
)
}
let didDeleteSectionExpectation = self.expectationForNotification(
"listMonitor:didDeleteSection:fromSectionIndex:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 3)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
["sectionInfo", "sectionIndex"]
)
let sectionInfo = userInfo?["sectionInfo"]
XCTAssertNotNil(sectionInfo)
XCTAssertEqual(sectionInfo?.name, "0")
let sectionIndex = userInfo?["sectionIndex"]
XCTAssertEqual(sectionIndex as? NSNumber, NSNumber(integer: 0))
defer {
events += 1
}
return events == 3
}
)
let didChangeExpectation = self.expectationForNotification(
"listMonitorDidChange:",
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 4)
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
defer {
events += 1
}
return events == 4
}
)
let saveExpectation = self.expectationWithDescription("save")
stack.beginAsynchronous { (transaction) in
transaction.deleteAll(
From(TestEntity1),
Where("testBoolean", isEqualTo: false)
)
transaction.commit { (result) in
switch result {
case .Success(let hasChanges):
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
case .Failure:
XCTFail()
}
}
}
self.waitAndCheckExpectations()
}
}
}

View File

@@ -40,7 +40,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
From(TestEntity1),
@@ -63,6 +63,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual(
(note.userInfo ?? [:]),
["object": object] as NSDictionary
@@ -79,6 +80,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 1)
XCTAssertEqual(
(note.userInfo ?? [:]),
[
@@ -89,7 +91,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
"testString"
]
)
] as NSDictionary
] as NSDictionary
)
let object = note.userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testNumber, NSNumber(integer: 10))
@@ -135,7 +137,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack, configurations: [nil])
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
From(TestEntity1),
@@ -158,6 +160,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
object: observer,
handler: { (note) -> Bool in
XCTAssertEqual(events, 0)
XCTAssertEqual(
(note.userInfo ?? [:]),
["object": object] as NSDictionary