diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 02af12f..32723ed 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -67,8 +67,6 @@ 82BA18D71C4BBD7100A0916E /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; }; 82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; }; 82BA18D91C4BBD9700A0916E /* CoreStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F03A53F19C5C6DA005002A5 /* CoreStoreTests.swift */; }; - 82BA18DA1C4BBD9700A0916E /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D372851A39CDDB00F583D9 /* TestEntity1.swift */; }; - 82BA18DB1C4BBD9700A0916E /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */; }; 82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; }; 82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; }; 82BA18DF1C4BBE2600A0916E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82BA18DE1C4BBE2600A0916E /* Foundation.framework */; }; @@ -160,8 +158,6 @@ B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; }; B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; }; B52DD1CC1BE1F94D00949AFE /* CoreStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F03A53F19C5C6DA005002A5 /* CoreStoreTests.swift */; }; - B52DD1CD1BE1F94D00949AFE /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D372851A39CDDB00F583D9 /* TestEntity1.swift */; }; - B52DD1CE1BE1F94D00949AFE /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */; }; B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; B53FB9FF1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; @@ -207,6 +203,21 @@ B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; }; B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; }; B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; }; + B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; }; + B5489F401CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; }; + B5489F411CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; }; + B5489F421CF5EEBC008B4978 /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */; }; + B5489F431CF5EEBC008B4978 /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */; }; + B5489F441CF5EEBC008B4978 /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */; }; + B5489F461CF5F017008B4978 /* TransactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F451CF5F017008B4978 /* TransactionTests.swift */; }; + B5489F471CF5F017008B4978 /* TransactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F451CF5F017008B4978 /* TransactionTests.swift */; }; + B5489F481CF5F017008B4978 /* TransactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F451CF5F017008B4978 /* TransactionTests.swift */; }; + B5489F4C1CF5F743008B4978 /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */; }; + B5489F4D1CF5F743008B4978 /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */; }; + B5489F4E1CF5F743008B4978 /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */; }; + B5489F501CF603D5008B4978 /* ClauseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* ClauseTests.swift */; }; + B5489F511CF603D5008B4978 /* ClauseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* ClauseTests.swift */; }; + B5489F521CF603D5008B4978 /* ClauseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* ClauseTests.swift */; }; B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */; }; B5519A401CA1B17B002BEF78 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */; }; B5519A411CA1B17B002BEF78 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */; }; @@ -302,9 +313,6 @@ B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; }; B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; }; B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; }; - B580857E1CDF8149004C2EEB /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B580857D1CDF8149004C2EEB /* BaseTestCase.swift */; }; - B580857F1CDF8149004C2EEB /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B580857D1CDF8149004C2EEB /* BaseTestCase.swift */; }; - B58085801CDF8149004C2EEB /* BaseTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B580857D1CDF8149004C2EEB /* BaseTestCase.swift */; }; B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; }; B59851491C90289D00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; }; B598514A1C90289E00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; }; @@ -334,13 +342,11 @@ B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; }; - B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D372851A39CDDB00F583D9 /* TestEntity1.swift */; }; B5D39A0219FD00C9000E91BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D39A0119FD00C9000E91BB /* Foundation.framework */; }; B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; }; - B5D5E0CF1A4D6AAB006468AF /* TestEntity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */; }; B5D7A5AF1CA3B738005C752B /* (null) in Sources */ = {isa = PBXBuildFile; }; B5D7A5B01CA3B738005C752B /* StorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA11C8481E100FA6A91 /* StorageInterface.swift */; }; B5D7A5B11CA3B738005C752B /* InMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */; }; @@ -654,6 +660,11 @@ B546F95C1C9A12B800D5AC55 /* CSSQliteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSQliteStore.swift; sourceTree = ""; }; B546F9681C9AF26D00D5AC55 /* CSInMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInMemoryStore.swift; sourceTree = ""; }; B546F9721C9C553300D5AC55 /* SetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupResult.swift; sourceTree = ""; }; + B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = ""; }; + B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = ""; }; + B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = ""; }; + B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestCase.swift; sourceTree = ""; }; + B5489F4F1CF603D5008B4978 /* ClauseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClauseTests.swift; sourceTree = ""; }; B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchedResultsControllerDelegate.swift; sourceTree = ""; }; B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; B5519A491CA1F4FB002BEF78 /* CSError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSError.swift; sourceTree = ""; }; @@ -673,7 +684,6 @@ B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DataStack+Migration.swift"; sourceTree = ""; }; B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = ""; }; B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = ""; }; - B580857D1CDF8149004C2EEB /* BaseTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestCase.swift; sourceTree = ""; }; B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPersistentStoreCoordinator+Setup.swift"; sourceTree = ""; }; B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = ""; }; B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = ""; }; @@ -686,10 +696,8 @@ B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = ""; }; B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = ""; }; B5D372831A39CD6900F583D9 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; - B5D372851A39CDDB00F583D9 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = ""; }; B5D39A0119FD00C9000E91BB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = ""; }; - B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = ""; }; B5D7A5B51CA3BF8F005C752B /* CSInto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInto.swift; sourceTree = ""; }; B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; }; B5D9E3341CA2C317007A9D52 /* CoreStore_iOS7.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore_iOS7.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -903,17 +911,18 @@ 2F03A53C19C5C6DA005002A5 /* CoreStoreTests */ = { isa = PBXGroup; children = ( + B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */, + B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */, B58085741CDF7F00004C2EEB /* SetupTests.swift */, - 2F03A53F19C5C6DA005002A5 /* CoreStoreTests.swift */, B5DC47C91C93D9C800FA3BF3 /* StorageInterfaceTests.swift */, + B5489F4F1CF603D5008B4978 /* ClauseTests.swift */, + B5489F451CF5F017008B4978 /* TransactionTests.swift */, + 2F03A53F19C5C6DA005002A5 /* CoreStoreTests.swift */, B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */, B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */, - B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */, - B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */, - B5D372851A39CDDB00F583D9 /* TestEntity1.swift */, - B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */, + B5489F4A1CF5F743008B4978 /* BaseTests */, + B5489F3C1CF5EEBC008B4978 /* TestEntities */, 2F03A53D19C5C6DA005002A5 /* Supporting Files */, - B580857D1CDF8149004C2EEB /* BaseTestCase.swift */, ); path = CoreStoreTests; sourceTree = ""; @@ -989,6 +998,23 @@ name = StorageInterfaces; sourceTree = ""; }; + B5489F3C1CF5EEBC008B4978 /* TestEntities */ = { + isa = PBXGroup; + children = ( + B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */, + B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */, + ); + path = TestEntities; + sourceTree = ""; + }; + B5489F4A1CF5F743008B4978 /* BaseTests */ = { + isa = PBXGroup; + children = ( + B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */, + ); + path = BaseTests; + sourceTree = ""; + }; B5519A5D1CA20093002BEF78 /* Transactions */ = { isa = PBXGroup; children = ( @@ -1686,13 +1712,15 @@ files = ( B5519A401CA1B17B002BEF78 /* ErrorTests.swift in Sources */, 2F03A54019C5C6DA005002A5 /* CoreStoreTests.swift in Sources */, - B580857E1CDF8149004C2EEB /* BaseTestCase.swift in Sources */, B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, - B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */, B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */, + B5489F501CF603D5008B4978 /* ClauseTests.swift in Sources */, + B5489F421CF5EEBC008B4978 /* TestEntity2.swift in Sources */, + B5489F461CF5F017008B4978 /* TransactionTests.swift in Sources */, B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */, + B5489F4C1CF5F743008B4978 /* BaseTestCase.swift in Sources */, B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */, - B5D5E0CF1A4D6AAB006468AF /* TestEntity2.swift in Sources */, + B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */, B5DC47CA1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1818,14 +1846,16 @@ buildActionMask = 2147483647; files = ( B5519A411CA1B17B002BEF78 /* ErrorTests.swift in Sources */, - 82BA18DA1C4BBD9700A0916E /* TestEntity1.swift in Sources */, - B580857F1CDF8149004C2EEB /* BaseTestCase.swift in Sources */, B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, - 82BA18DB1C4BBD9700A0916E /* TestEntity2.swift in Sources */, B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */, B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */, + B5489F511CF603D5008B4978 /* ClauseTests.swift in Sources */, + B5489F431CF5EEBC008B4978 /* TestEntity2.swift in Sources */, + B5489F471CF5F017008B4978 /* TransactionTests.swift in Sources */, 82BA18D91C4BBD9700A0916E /* CoreStoreTests.swift in Sources */, + B5489F4D1CF5F743008B4978 /* BaseTestCase.swift in Sources */, 82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */, + B5489F401CF5EEBC008B4978 /* TestEntity1.swift in Sources */, B5DC47CB1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1932,14 +1962,16 @@ buildActionMask = 2147483647; files = ( B5519A421CA1B17B002BEF78 /* ErrorTests.swift in Sources */, - B52DD1CD1BE1F94D00949AFE /* TestEntity1.swift in Sources */, - B58085801CDF8149004C2EEB /* BaseTestCase.swift in Sources */, B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, - B52DD1CE1BE1F94D00949AFE /* TestEntity2.swift in Sources */, B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */, B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */, + B5489F521CF603D5008B4978 /* ClauseTests.swift in Sources */, + B5489F441CF5EEBC008B4978 /* TestEntity2.swift in Sources */, + B5489F481CF5F017008B4978 /* TransactionTests.swift in Sources */, B52DD1CC1BE1F94D00949AFE /* CoreStoreTests.swift in Sources */, + B5489F4E1CF5F743008B4978 /* BaseTestCase.swift in Sources */, B5598BCC1BE2093D0092EFCE /* Model.xcdatamodeld in Sources */, + B5489F411CF5EEBC008B4978 /* TestEntity1.swift in Sources */, B5DC47CC1C93D9C800FA3BF3 /* StorageInterfaceTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/CoreStoreTests/BaseTestCase.swift b/CoreStoreTests/BaseTestCase.swift deleted file mode 100644 index 19707ae..0000000 --- a/CoreStoreTests/BaseTestCase.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// BaseTestCase.swift -// CoreStore -// -// Created by John Rommel Estropia on 2016/05/08. -// Copyright © 2016 John Rommel Estropia. All rights reserved. -// - -import XCTest - -@testable -import CoreStore - - -// MARK: - BaseTestCase - -class BaseTestCase: XCTestCase { - - // MARK: XCTestCase - - override func setUp() { - - super.setUp() - self.deleteStores() - } - - override func tearDown() { - - self.deleteStores() - super.tearDown() - } - - - // MARK: Private - - private func deleteStores() { - - _ = try? NSFileManager.defaultManager().removeItemAtURL(SQLiteStore.defaultRootDirectory) - } -} diff --git a/CoreStoreTests/BaseTests/BaseTestCase.swift b/CoreStoreTests/BaseTests/BaseTestCase.swift new file mode 100644 index 0000000..b309415 --- /dev/null +++ b/CoreStoreTests/BaseTests/BaseTestCase.swift @@ -0,0 +1,84 @@ +// +// BaseTestCase.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: - BaseTestCase + +class BaseTestCase: XCTestCase { + + // MARK: Internal + + @nonobjc + func prepareStack(configuration: String = "Config1", @noescape _ closure: (dataStack: DataStack) -> Void) { + + let stack = DataStack( + modelName: "Model", + bundle: NSBundle(forClass: self.dynamicType) + ) + do { + + try stack.addStorageAndWait( + SQLiteStore( + fileName: "\(self.dynamicType).sqlite", + configuration: configuration, + localStorageOptions: .RecreateStoreOnModelMismatch + ) + ) + } + catch let error as NSError { + + XCTFail(error.coreStoreDumpString) + } + closure(dataStack: stack) + } + + + // MARK: XCTestCase + + override func setUp() { + + super.setUp() + self.deleteStores() + } + + override func tearDown() { + + self.deleteStores() + super.tearDown() + } + + + // MARK: Private + + private func deleteStores(directory: NSURL = SQLiteStore.defaultRootDirectory) { + + _ = try? NSFileManager.defaultManager().removeItemAtURL(directory) + } +} diff --git a/CoreStoreTests/ClauseTests.swift b/CoreStoreTests/ClauseTests.swift new file mode 100644 index 0000000..6c032da --- /dev/null +++ b/CoreStoreTests/ClauseTests.swift @@ -0,0 +1,43 @@ +// +// ClauseTests.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: - ClauseTests + +final class ClauseTests: XCTestCase { + + // MARK: Into + + @objc + dynamic func test_IntoClauses_ConfigureCorrectly() { + + // TODO: + } +} diff --git a/CoreStoreTests/ErrorTests.swift b/CoreStoreTests/ErrorTests.swift index d12fed5..7276015 100644 --- a/CoreStoreTests/ErrorTests.swift +++ b/CoreStoreTests/ErrorTests.swift @@ -28,132 +28,142 @@ import XCTest @testable import CoreStore -class ErrorTests: XCTestCase { - func testErrors() { +// MARK: - ErrorTests + +final class ErrorTests: XCTestCase { + + @objc + dynamic func test_ThatUnknownErrors_BridgeCorrectly() { - do { - - let error = CoreStoreError.Unknown - XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) - XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.UnknownError.rawValue) - - let userInfo: NSDictionary = [:] - - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) - XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError.code, CoreStoreErrorCode.UnknownError.rawValue) - XCTAssertEqual(objcError.userInfo, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) - XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError2.code, CoreStoreErrorCode.UnknownError.rawValue) - XCTAssertEqual(objcError2.userInfo, userInfo) - } + let error = CoreStoreError.Unknown + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.UnknownError.rawValue) + + let userInfo: NSDictionary = [:] + + let objcError = error.bridgeToObjectiveC + XCTAssertEqual(error, objcError.bridgeToSwift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.UnknownError.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC + XCTAssertEqual(error, objcError2.bridgeToSwift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.UnknownError.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + @objc + dynamic func test_ThatDifferentStorageExistsAtURLErrors_BridgeCorrectly() { let dummyURL = NSURL(string: "file:///test1/test2.sqlite")! - do { - - let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: dummyURL) - XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) - XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) - - let userInfo: NSDictionary = [ - "existingPersistentStoreURL": dummyURL - ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) - XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) - XCTAssertEqual(objcError.userInfo, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) - XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError2.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) - XCTAssertEqual(objcError2.userInfo, userInfo) - } - do { - - let model = NSManagedObjectModel.fromBundle(NSBundle(forClass: self.dynamicType), modelName: "Model") - let version = "1.0.0" - - let error = CoreStoreError.MappingModelNotFound(localStoreURL: dummyURL, targetModel: model, targetModelVersion: version) - XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) - XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.MappingModelNotFound.rawValue) - - let userInfo: NSDictionary = [ - "localStoreURL": dummyURL, - "targetModel": model, - "targetModelVersion": version - ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) - XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) - XCTAssertEqual(objcError.userInfo, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) - XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError2.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) - XCTAssertEqual(objcError2.userInfo, userInfo) - } + let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: dummyURL) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) - do { - - let error = CoreStoreError.ProgressiveMigrationRequired(localStoreURL: dummyURL) - XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) - XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) - - let userInfo: NSDictionary = [ - "localStoreURL": dummyURL - ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) - XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) - XCTAssertEqual(objcError.userInfo, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) - XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError2.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) - XCTAssertEqual(objcError2.userInfo, userInfo) - } + let userInfo: NSDictionary = [ + "existingPersistentStoreURL": dummyURL + ] + let objcError = error.bridgeToObjectiveC + XCTAssertEqual(error, objcError.bridgeToSwift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) - do { - - let internalError = NSError( - domain: "com.dummy", - code: 123, - userInfo: [ - "key1": "value1", - "key2": 2, - "key3": NSDate() - ] - ) - let error = CoreStoreError.InternalError(NSError: internalError) - XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) - XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.InternalError.rawValue) - - let userInfo: NSDictionary = [ - "NSError": internalError + let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC + XCTAssertEqual(error, objcError2.bridgeToSwift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + @objc + dynamic func test_ThatMappingModelNotFoundErrors_BridgeCorrectly() { + + let dummyURL = NSURL(string: "file:///test1/test2.sqlite")! + + let model = NSManagedObjectModel.fromBundle(NSBundle(forClass: self.dynamicType), modelName: "Model") + let version = "1.0.0" + + let error = CoreStoreError.MappingModelNotFound(localStoreURL: dummyURL, targetModel: model, targetModelVersion: version) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + + let userInfo: NSDictionary = [ + "localStoreURL": dummyURL, + "targetModel": model, + "targetModelVersion": version + ] + let objcError = error.bridgeToObjectiveC + XCTAssertEqual(error, objcError.bridgeToSwift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC + XCTAssertEqual(error, objcError2.bridgeToSwift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + @objc + dynamic func test_ThatProgressiveMigrationRequiredErrors_BridgeCorrectly() { + + let dummyURL = NSURL(string: "file:///test1/test2.sqlite")! + + let error = CoreStoreError.ProgressiveMigrationRequired(localStoreURL: dummyURL) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + + let userInfo: NSDictionary = [ + "localStoreURL": dummyURL + ] + let objcError = error.bridgeToObjectiveC + XCTAssertEqual(error, objcError.bridgeToSwift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC + XCTAssertEqual(error, objcError2.bridgeToSwift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + @objc + dynamic func test_ThatInternalErrorErrors_BridgeCorrectly() { + + let internalError = NSError( + domain: "com.dummy", + code: 123, + userInfo: [ + "key1": "value1", + "key2": 2, + "key3": NSDate() ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) - XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError.code, CoreStoreErrorCode.InternalError.rawValue) - XCTAssertEqual(objcError.userInfo, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) - XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) - XCTAssertEqual(objcError2.code, CoreStoreErrorCode.InternalError.rawValue) - XCTAssertEqual(objcError2.userInfo, userInfo) - } + ) + let error = CoreStoreError.InternalError(NSError: internalError) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.InternalError.rawValue) + + let userInfo: NSDictionary = [ + "NSError": internalError + ] + let objcError = error.bridgeToObjectiveC + XCTAssertEqual(error, objcError.bridgeToSwift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.InternalError.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC + XCTAssertEqual(error, objcError2.bridgeToSwift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.InternalError.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) } } diff --git a/CoreStoreTests/MigrationChainTests.swift b/CoreStoreTests/MigrationChainTests.swift index 5c550a9..25e2616 100644 --- a/CoreStoreTests/MigrationChainTests.swift +++ b/CoreStoreTests/MigrationChainTests.swift @@ -28,9 +28,13 @@ import XCTest @testable import CoreStore -class MigrationChainTests: XCTestCase { + +// MARK: - MigrationChainTests + +final class MigrationChainTests: XCTestCase { - @objc dynamic func testEmptyChain() { + @objc + dynamic func test_ThatNilMigrationChains_HaveNoVersions() { let chain: MigrationChain = nil XCTAssertTrue(chain.valid) @@ -40,7 +44,8 @@ class MigrationChainTests: XCTestCase { XCTAssertNil(chain.nextVersionFrom("version1")) } - @objc dynamic func testSingleChain() { + @objc + dynamic func test_ThatStringMigrationChains_HaveOneVersion() { let chain: MigrationChain = "version1" XCTAssertTrue(chain.valid) @@ -53,7 +58,8 @@ class MigrationChainTests: XCTestCase { XCTAssertNil(chain.nextVersionFrom("version2")) } - @objc dynamic func testLinearChain() { + @objc + dynamic func test_ThatArrayMigrationChains_HaveLinearVersions() { let chain: MigrationChain = ["version1", "version2", "version3", "version4"] XCTAssertTrue(chain.valid) @@ -72,7 +78,8 @@ class MigrationChainTests: XCTestCase { XCTAssertNil(chain.nextVersionFrom("version5")) } - @objc dynamic func testTreeChain() { + @objc + dynamic func test_ThatDictionaryMigrationChains_HaveTreeVersions() { let chain: MigrationChain = [ "version1": "version4", @@ -94,17 +101,47 @@ class MigrationChainTests: XCTestCase { XCTAssertNil(chain.nextVersionFrom("version4")) XCTAssertNil(chain.nextVersionFrom("version5")) - // The cases below will trigger assertion failures internally +// The cases below will trigger assertion failures internally + +// let linearLoopChain: MigrationChain = ["version1", "version2", "version1", "version3", "version4"] +// XCTAssertFalse(linearLoopChain.valid, "linearLoopChain.valid") +// +// let treeAmbiguousChain: MigrationChain = [ +// "version1": "version4", +// "version2": "version3", +// "version1": "version2", +// "version3": "version4" +// ] +// XCTAssertFalse(treeAmbiguousChain.valid, "treeAmbiguousChain.valid") + } + + @objc + dynamic func test_ThatMigrationChains_AreEquatable() { - // let linearLoopChain: MigrationChain = ["version1", "version2", "version1", "version3", "version4"] - // XCTAssertFalse(linearLoopChain.valid, "linearLoopChain.valid") - // - // let treeAmbiguousChain: MigrationChain = [ - // "version1": "version4", - // "version2": "version3", - // "version1": "version2", - // "version3": "version4" - // ] - // XCTAssertFalse(treeAmbiguousChain.valid, "treeAmbiguousChain.valid") + do { + + let chain1: MigrationChain = nil + let chain2: MigrationChain = [] + let chain3: MigrationChain = [:] + XCTAssertEqual(chain1, chain2) + XCTAssertEqual(chain2, chain3) + XCTAssertEqual(chain3, chain1) + } + do { + + let chain1: MigrationChain = "version1" + let chain2: MigrationChain = ["version1"] + XCTAssertEqual(chain1, chain2) + } + do { + + let chain1: MigrationChain = ["version1", "version2", "version3", "version4"] + let chain2: MigrationChain = [ + "version1": "version2", + "version2": "version3", + "version3": "version4" + ] + XCTAssertEqual(chain1, chain2) + } } } diff --git a/CoreStoreTests/SetupTests.swift b/CoreStoreTests/SetupTests.swift index 4bf449c..0b82d71 100644 --- a/CoreStoreTests/SetupTests.swift +++ b/CoreStoreTests/SetupTests.swift @@ -31,28 +31,105 @@ import CoreStore class SetupTests: BaseTestCase { - func testInMemoryStores() { + @objc + dynamic func test_ThatDataStacks_ConfigureCorrectly() { + + do { + + let model = NSManagedObjectModel.mergedModelFromBundles([NSBundle(forClass: self.dynamicType)])! + + let stack = DataStack(model: model, migrationChain: nil) + XCTAssertEqual(stack.model, model) + XCTAssertTrue(stack.migrationChain.valid) + XCTAssertTrue(stack.migrationChain.empty) + XCTAssertTrue(stack.migrationChain.rootVersions.isEmpty) + XCTAssertTrue(stack.migrationChain.leafVersions.isEmpty) + + CoreStore.defaultStack = stack + XCTAssertEqual(CoreStore.defaultStack, stack) + } + do { + + let migrationChain: MigrationChain = ["version1", "version2", "version3"] + + let stack = DataStack( + modelName: "Model", + bundle: NSBundle(forClass: self.dynamicType), + migrationChain: migrationChain + ) + XCTAssertEqual(stack.modelVersion, "Model") + XCTAssertEqual(stack.migrationChain, migrationChain) + + CoreStore.defaultStack = stack + XCTAssertEqual(CoreStore.defaultStack, stack) + } + } + + @objc + dynamic func test_ThatInMemoryStores_SetupCorrectly() { let stack = DataStack( modelName: "Model", bundle: NSBundle(forClass: self.dynamicType) ) - CoreStore.defaultStack = stack - XCTAssertEqual(CoreStore.defaultStack, stack) - XCTAssertEqual(stack.modelVersion, "Model") - XCTAssert(stack.migrationChain.valid) - XCTAssert(stack.migrationChain.empty) - XCTAssert(stack.migrationChain.rootVersions.isEmpty) - XCTAssert(stack.migrationChain.leafVersions.isEmpty) + do { + + let inMemoryStore = InMemoryStore() + do { + + try stack.addStorageAndWait(inMemoryStore) + } + catch let error as NSError { + + XCTFail(error.description) + } + let persistentStore = stack.persistentStoreForStorage(inMemoryStore) + XCTAssertNotNil(persistentStore) + } + do { + + let inMemoryStore = InMemoryStore( + configuration: "Config1" + ) + do { + + try stack.addStorageAndWait(inMemoryStore) + } + catch let error as NSError { + + XCTFail(error.description) + } + let persistentStore = stack.persistentStoreForStorage(inMemoryStore) + XCTAssertNotNil(persistentStore) + } + do { + + let inMemoryStore = InMemoryStore( + configuration: "Config2" + ) + do { + + try stack.addStorageAndWait(inMemoryStore) + } + catch let error as NSError { + + XCTFail(error.description) + } + let persistentStore = stack.persistentStoreForStorage(inMemoryStore) + XCTAssertNotNil(persistentStore) + } + } + + @objc + dynamic func test_ThatSQLiteStores_SetupCorrectly() { + let stack = DataStack( + modelName: "Model", + bundle: NSBundle(forClass: self.dynamicType) + ) do { let sqliteStore = SQLiteStore() - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultFileURL) - XCTAssertEqual(sqliteStore.configuration, nil) - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.None) - do { try stack.addStorageAndWait(sqliteStore) @@ -65,7 +142,6 @@ class SetupTests: BaseTestCase { XCTAssertNotNil(persistentStore) XCTAssert(sqliteStore.matchesPersistentStore(persistentStore!)) } - do { let sqliteStore = SQLiteStore( @@ -73,12 +149,6 @@ class SetupTests: BaseTestCase { configuration: "Config1", localStorageOptions: .RecreateStoreOnModelMismatch ) - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultRootDirectory - .URLByAppendingPathComponent("ConfigStore1.sqlite", isDirectory: false)) - XCTAssertEqual(sqliteStore.configuration, "Config1") - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.RecreateStoreOnModelMismatch) - do { try stack.addStorageAndWait(sqliteStore) @@ -91,7 +161,6 @@ class SetupTests: BaseTestCase { XCTAssertNotNil(persistentStore) XCTAssert(sqliteStore.matchesPersistentStore(persistentStore!)) } - do { let sqliteStore = SQLiteStore( @@ -99,12 +168,6 @@ class SetupTests: BaseTestCase { configuration: "Config2", localStorageOptions: .RecreateStoreOnModelMismatch ) - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultRootDirectory - .URLByAppendingPathComponent("ConfigStore2.sqlite", isDirectory: false)) - XCTAssertEqual(sqliteStore.configuration, "Config2") - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.RecreateStoreOnModelMismatch) - do { try stack.addStorageAndWait(sqliteStore) @@ -119,28 +182,16 @@ class SetupTests: BaseTestCase { } } - func testSQLiteStores() { + @objc + dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() { let stack = DataStack( modelName: "Model", bundle: NSBundle(forClass: self.dynamicType) ) - CoreStore.defaultStack = stack - XCTAssertEqual(CoreStore.defaultStack, stack) - XCTAssertEqual(stack.modelVersion, "Model") - XCTAssert(stack.migrationChain.valid) - XCTAssert(stack.migrationChain.empty) - XCTAssert(stack.migrationChain.rootVersions.isEmpty) - XCTAssert(stack.migrationChain.leafVersions.isEmpty) - do { let sqliteStore = SQLiteStore() - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultFileURL) - XCTAssertEqual(sqliteStore.configuration, nil) - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.None) - do { try stack.addStorageAndWait(sqliteStore) @@ -153,7 +204,6 @@ class SetupTests: BaseTestCase { XCTAssertNotNil(persistentStore) XCTAssert(sqliteStore.matchesPersistentStore(persistentStore!)) } - do { let sqliteStore = SQLiteStore( @@ -161,12 +211,6 @@ class SetupTests: BaseTestCase { configuration: "Config1", localStorageOptions: .RecreateStoreOnModelMismatch ) - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultRootDirectory - .URLByAppendingPathComponent("ConfigStore1.sqlite", isDirectory: false)) - XCTAssertEqual(sqliteStore.configuration, "Config1") - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.RecreateStoreOnModelMismatch) - do { try stack.addStorageAndWait(sqliteStore) @@ -179,7 +223,6 @@ class SetupTests: BaseTestCase { XCTAssertNotNil(persistentStore) XCTAssert(sqliteStore.matchesPersistentStore(persistentStore!)) } - do { let sqliteStore = SQLiteStore( @@ -187,12 +230,6 @@ class SetupTests: BaseTestCase { configuration: "Config2", localStorageOptions: .RecreateStoreOnModelMismatch ) - XCTAssertEqual(sqliteStore.fileURL, SQLiteStore.defaultRootDirectory - .URLByAppendingPathComponent("ConfigStore2.sqlite", isDirectory: false)) - XCTAssertEqual(sqliteStore.configuration, "Config2") - XCTAssertEqual(sqliteStore.mappingModelBundles, NSBundle.allBundles()) - XCTAssertEqual(sqliteStore.localStorageOptions, LocalStorageOptions.RecreateStoreOnModelMismatch) - do { try stack.addStorageAndWait(sqliteStore) diff --git a/CoreStoreTests/StorageInterfaceTests.swift b/CoreStoreTests/StorageInterfaceTests.swift index 6530fce..8c2e494 100644 --- a/CoreStoreTests/StorageInterfaceTests.swift +++ b/CoreStoreTests/StorageInterfaceTests.swift @@ -28,9 +28,13 @@ import XCTest @testable import CoreStore -class StorageInterfaceTests: XCTestCase { - func testDefaultInMemoryStore() { +//MARK: - StorageInterfaceTests + +final class StorageInterfaceTests: XCTestCase { + + @objc + dynamic func test_ThatDefaultInMemoryStores_ConfigureCorrectly() { let store = InMemoryStore() XCTAssertEqual(store.dynamicType.storeType, NSInMemoryStoreType) @@ -38,7 +42,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertNil(store.storeOptions) } - func testInMemoryStoreConfiguration() { + @objc + dynamic func test_ThatCustomInMemoryStores_ConfigureCorrectly() { let store = InMemoryStore(configuration: "config1") XCTAssertEqual(store.dynamicType.storeType, NSInMemoryStoreType) @@ -46,7 +51,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertNil(store.storeOptions) } - func testSQLiteStoreDefaultDirectories() { + @objc + dynamic func test_ThatSQLiteStoreDefaultDirectories_AreCorrect() { #if os(tvOS) let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory @@ -72,7 +78,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(SQLiteStore.defaultFileURL, defaultFileURL) } - func testDefaultSQLiteStore() { + @objc + dynamic func test_ThatDefaultSQLiteStores_ConfigureCorrectly() { let store = SQLiteStore() XCTAssertEqual(store.dynamicType.storeType, NSSQLiteStoreType) @@ -84,7 +91,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(store.localStorageOptions, [.None]) } - func testSQLiteStoreFileURL() { + @objc + dynamic func test_ThatFileURLSQLiteStores_ConfigureCorrectly() { let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) .URLByAppendingPathComponent(NSUUID().UUIDString, isDirectory: false) @@ -106,7 +114,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(store.localStorageOptions, [.RecreateStoreOnModelMismatch]) } - func testSQLiteStoreFileName() { + @objc + dynamic func test_ThatFileNameSQLiteStores_ConfigureCorrectly() { let fileName = NSUUID().UUIDString + ".db" let bundles = [NSBundle(forClass: self.dynamicType)] @@ -127,7 +136,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(store.localStorageOptions, [.RecreateStoreOnModelMismatch]) } - func testLegacySQLiteStoreDefaultDirectories() { + @objc + dynamic func test_ThatLegacySQLiteStoreDefaultDirectories_AreCorrect() { #if os(tvOS) let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory @@ -148,7 +158,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(LegacySQLiteStore.defaultFileURL, legacyDefaultFileURL) } - func testDefaultLegacySQLiteStore() { + @objc + dynamic func test_ThatDefaultLegacySQLiteStores_ConfigureCorrectly() { let store = LegacySQLiteStore() XCTAssertEqual(store.dynamicType.storeType, NSSQLiteStoreType) @@ -160,7 +171,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(store.localStorageOptions, [.None]) } - func testLegacySQLiteStoreFileURL() { + @objc + dynamic func test_ThatFileURLLegacySQLiteStores_ConfigureCorrectly() { let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) .URLByAppendingPathComponent(NSUUID().UUIDString, isDirectory: false) @@ -182,7 +194,8 @@ class StorageInterfaceTests: XCTestCase { XCTAssertEqual(store.localStorageOptions, [.RecreateStoreOnModelMismatch]) } - func testLegacySQLiteStoreFileName() { + @objc + dynamic func test_ThatFileNameLegacySQLiteStores_ConfigureCorrectly() { let fileName = NSUUID().UUIDString + ".db" let bundles = [NSBundle(forClass: self.dynamicType)] diff --git a/CoreStoreTests/TestEntity1.swift b/CoreStoreTests/TestEntities/TestEntity1.swift similarity index 100% rename from CoreStoreTests/TestEntity1.swift rename to CoreStoreTests/TestEntities/TestEntity1.swift diff --git a/CoreStoreTests/TestEntity2.swift b/CoreStoreTests/TestEntities/TestEntity2.swift similarity index 100% rename from CoreStoreTests/TestEntity2.swift rename to CoreStoreTests/TestEntities/TestEntity2.swift diff --git a/CoreStoreTests/TransactionTests.swift b/CoreStoreTests/TransactionTests.swift new file mode 100644 index 0000000..3a610b5 --- /dev/null +++ b/CoreStoreTests/TransactionTests.swift @@ -0,0 +1,46 @@ +// +// TransactionTests.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: - TransactionTests + +final class TransactionTests: BaseTestCase { + + @objc + dynamic func test_ThatSynchronousTransactions_ConfigureCorrectly() { + + self.prepareStack { (stack) in + + // TODO: + } + } + + // MARK: Private +} diff --git a/Sources/Migrating/MigrationChain.swift b/Sources/Migrating/MigrationChain.swift index 0567082..2d5c861 100644 --- a/Sources/Migrating/MigrationChain.swift +++ b/Sources/Migrating/MigrationChain.swift @@ -60,7 +60,7 @@ import CoreData - a version appears twice as a key in a dictionary literal - a loop is found in any of the paths */ -public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, DictionaryLiteralConvertible, ArrayLiteralConvertible { +public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, DictionaryLiteralConvertible, ArrayLiteralConvertible, Equatable { /** Initializes the `MigrationChain` with empty values, which instructs the `DataStack` to use the .xcdatamodel's current version as the final version, and to disable progressive migrations. @@ -248,3 +248,16 @@ public struct MigrationChain: NilLiteralConvertible, StringLiteralConvertible, D private let versionTree: [String: String] } + + +// MARK: - MigrationChain: Equatable + +@warn_unused_result +public func == (lhs: MigrationChain, rhs: MigrationChain) -> Bool { + + return lhs.versionTree == rhs.versionTree + && lhs.rootVersions == rhs.rootVersions + && lhs.leafVersions == rhs.leafVersions + && lhs.valid == rhs.valid +} + diff --git a/Sources/ObjectiveC/CSUnsafeDataTransaction.swift b/Sources/ObjectiveC/CSUnsafeDataTransaction.swift index 48cebfc..ff2dae5 100644 --- a/Sources/ObjectiveC/CSUnsafeDataTransaction.swift +++ b/Sources/ObjectiveC/CSUnsafeDataTransaction.swift @@ -92,6 +92,38 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction { self.bridgeToSwift.redo() } + /** + Immediately flushes all pending changes to the transaction's observers. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data. + + - Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`) + - parameter error: the `NSError` pointer that indicates the reason in case of an failure + */ + @objc + public func flush(error error: NSErrorPointer) { + + bridge(error) { + + try self.bridgeToSwift.flush() + } + } + + /** + Flushes all pending changes to the transaction's observers at the end of the `closure`'s execution. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data. + + - Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`) + - parameter error: the `NSError` pointer that indicates the reason in case of an failure + - parameter closure: the closure where changes can be made prior to the flush + */ + @objc + public func flush(error error: NSErrorPointer, block: () -> Void) throws { + + bridge(error) { + + block() + try self.bridgeToSwift.context.save() + } + } + /** Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. diff --git a/Sources/Transactions/NSManagedObject+Transaction.swift b/Sources/Transactions/NSManagedObject+Transaction.swift index f26279e..9e3a23a 100644 --- a/Sources/Transactions/NSManagedObject+Transaction.swift +++ b/Sources/Transactions/NSManagedObject+Transaction.swift @@ -36,7 +36,7 @@ public extension NSManagedObject { When using an `UnsafeDataTransaction` and passing around a temporary object, you can use this property to execute fetches and updates to the transaction without having to pass around both the object and the transaction instances. - - Note: The internal reference to the transaction is `weak`, and it is still the developer's responsibility to retain a strong reference to the `UnsafeDataTransaction`. + - Important: The internal reference to the transaction is `weak`, and it is still the developer's responsibility to retain a strong reference to the `UnsafeDataTransaction`. */ @nonobjc public var unsafeDataTransaction: UnsafeDataTransaction? {