Compare commits

..

559 Commits

Author SHA1 Message Date
John Estropia
5a0d27cf34 update test platforms 2024-10-31 16:37:46 +09:00
John Estropia
104def4611 bump min development version to iOS 16 and macOS 13 2024-10-31 14:05:02 +09:00
John Estropia
5dcf29011a Support typed errors. Misc formatting 2024-09-10 11:14:39 +09:00
John Estropia
c9e091a6a4 Merge pull request #510 from DavidTiimo/develop
issue #509 | Xcode 16.0 beta 6 error - "'CATransaction' is unavailable in watchOS"
2024-09-10 11:11:32 +09:00
David Hansson
010a79ef6a Reverse check, as only watch os is having troubles 2024-09-04 12:55:24 +02:00
David Hansson
9f9ecb4820 Only available for iOS 2024-09-04 12:35:08 +02:00
David Hansson
3fb2b5927b Comment out broken code for Xcode beta 2024-08-13 09:47:48 +02:00
John Estropia
7c2129e38f Deprecation of legacy ValueContainer and RelationshipContainer properties in favor of @Field propertyWrapper counterpart 2024-01-28 22:11:21 +09:00
John Estropia
4b6d9a54e7 fix pod lint 2023-10-03 18:52:14 +09:00
John Estropia
cbf101506c revert unit test momd for now 2023-10-03 18:08:19 +09:00
John Estropia
9045fbbf1b bump CoreStore and Swift compiler versions 2023-10-03 11:25:56 +09:00
John Estropia
0ee4dc89aa Make unit test momd file accessible from SwiftPM builds 2023-10-03 11:25:19 +09:00
John Estropia
30d5e0a64a silence warnings on ObjectSnapshot sendability 2023-07-18 16:02:32 +09:00
John Estropia
320c6145f8 Merge branch 'develop' into prototype/concurrency 2023-07-18 09:44:53 +09:00
John Estropia
7e37219315 update header for MIT license, move all operator declarations to one file 2023-06-15 16:05:14 +09:00
John Estropia
d8235cf2e5 Merge pull request #482 from JCSooHwanCho/develop
merge operator declaration in one file
2023-06-15 16:00:40 +09:00
John Estropia
5cc34ff2e4 Merge pull request #483 from JCSooHwanCho/inlinable
mark designated initializer with usableFromInline
2023-06-15 15:56:51 +09:00
JCSoohwancho
d4d76c87c9 mark designated initializer with usableFromInline 2023-06-15 15:19:55 +09:00
JCSoohwancho
073a1bdee3 merge operator declaration in one file 2023-06-15 14:22:00 +09:00
John Estropia
118bb685fc remove watchos from unit tests 2023-06-08 11:39:17 +09:00
John Estropia
5d0c4bf8ac update jazzy docs 2023-06-08 11:02:23 +09:00
John Estropia
a8bd937c68 version bump 2023-06-08 11:02:14 +09:00
John Estropia
7988d98b92 fix warnings 2023-06-07 14:17:10 +09:00
John Estropia
4b4ae61635 add conditional compilation 2023-06-07 13:43:11 +09:00
John Estropia
535b33ca75 test reverting back to unsafeDowncast 2023-06-07 13:40:25 +09:00
John Estropia
b88ade92d6 add tentative replacement methods for SR-13069 workarounds 2023-03-24 18:28:43 +09:00
John Estropia
a682f90aff mask ObjectSnapshot as Sendable 2023-01-31 16:44:33 +09:00
John Estropia
f7c3e42009 mark sendable closures 2023-01-31 09:50:06 +09:00
John Estropia
2559375491 Raise watchOS min version to 7.4 as supported by Xcode 14 unit tests 2022-09-13 09:26:21 +09:00
John Estropia
c923dfc12c fix unit testing for multi-platform module 2022-09-12 16:51:20 +09:00
John Estropia
a5936c1120 added watchOS unit test lane to make cocoapods linter happy 2022-09-12 13:56:47 +09:00
John Estropia
159448b36d update README 2022-09-12 11:57:32 +09:00
John Estropia
7ee91834ab update README 2022-09-12 11:53:06 +09:00
John Estropia
8faf44c166 version bump 2022-09-12 10:04:33 +09:00
John Estropia
7f4cfaf5a0 Allow unit-testing in SPM builds 2022-08-16 11:55:44 +08:00
John Estropia
da4ac192db async API prototypes 2022-07-10 10:39:45 +09:00
John Estropia
e9219682b5 Fix builds for Swift 5.6 and below 2022-07-08 16:49:43 +09:00
John Estropia
6264022ccf make CoreStoreError dynamicc initializer public 2022-07-08 14:07:32 +09:00
John Estropia
1ed819b38d Goodbye Objective-C... 2022-06-29 20:27:42 +09:00
John Estropia
afddd2edbd Updated Package.swift 2022-06-22 19:20:40 +09:00
John Estropia
d1f83badef Xcode 14, iOS 16 SDK (min iOS 13) 2022-06-19 17:56:42 +09:00
John Estropia
3317867a2f Fix warnings for Xcode 13.3 beta 2022-03-05 11:31:36 +09:00
John Estropia
f738848e8c update SPM 2021-09-22 22:07:21 +09:00
John Estropia
496145761a version bump 2021-09-22 20:30:40 +09:00
John Estropia
c54795db5a project cleanup 2021-09-22 20:09:32 +09:00
John Estropia
9a026afe40 goodbye ObjectiveC 2021-09-22 20:04:58 +09:00
John Estropia
bf10f4668c revert Objc method changes 2021-09-22 15:03:46 +09:00
John Estropia
a1a04aaf8a tag refetch methods with source identifiers 2021-09-15 19:38:59 +09:00
John Estropia
4ddfa95140 added mechanism to track transaction sources 2021-09-15 14:45:13 +09:00
John Estropia
45215c7a18 WIP 2021-08-25 20:13:14 +09:00
John Estropia
d2f1656fdd test copy-on-write for ListSnapshot 2021-08-25 09:37:20 +09:00
John Estropia
5fbb1ab09d Merge pull request #421 from xquezme/develop
Fix compound indexes for dynamic models
2021-07-20 09:26:17 +09:00
John Estropia
d0cc01877e Merge pull request #433 from tackgyu/unset-library-type
Unset library type in Swift package manifests
2021-07-19 13:35:39 +09:00
tackgyu
a434628249 Unset library type in Swift package manifests 2021-07-19 12:52:51 +09:00
John Estropia
9cc616f720 fix compiler error on Xcode 13 2021-06-19 15:49:45 +09:00
John Estropia
4534bc06f5 Add utility for DiffableDataSources to create an empty snapshot for custom list construction 2021-06-16 23:28:46 +09:00
John Estropia
798d30bbd9 allow ListPublisher and ObjectPublisher combine Publishers to cancel subscription from any thread 2021-06-13 14:36:22 +09:00
John Estropia
7938aa2447 Added fast index-based ListSnapshot mutators 2021-06-12 11:06:43 +09:00
John Estropia
dda69389eb Fix SPM issues 2021-04-20 18:30:14 +09:00
John Estropia
b20be10a19 update Readme banner image 2021-04-11 11:39:43 +09:00
John Estropia
0ee8fbabd5 version bump, update resources 2021-04-11 11:26:02 +09:00
John Estropia
1f562b25a7 Updated README 2021-04-11 11:03:17 +09:00
Pimenov Sergey
6a2394052c fix compound indexes for dynamic models 2021-04-04 20:12:40 -07:00
John Estropia
593c0510d3 Allow placeholder Views in ObjectReader when an object becomes nil 2021-03-13 11:25:27 +09:00
John Estropia
338e4ddc9f Fix sig abort error 2021-03-07 17:02:09 +09:00
John Estropia
bfb1df3c40 added Publishers for addStorage functions 2021-03-07 16:08:19 +09:00
John Estropia
003bf897e2 Cleanup unnecessary #available branches 2021-03-07 12:01:08 +09:00
John Estropia
0b127956d3 Removed ObservableObject implementations of ListPublisher/ObjectPublisher in favor of LiveList/LiveObject and ".reactive" publishers 2021-03-07 10:38:53 +09:00
John Estropia
098e560fcc Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2021-03-07 10:17:34 +09:00
John Estropia
7dbd3777ec added sugar syntax for ForEach that removes requirement for the "id:" argument 2021-03-07 10:17:20 +09:00
John Estropia
447d8e5880 fix compile error 2021-03-03 16:59:20 +09:00
John Estropia
1f97225efa SwiftUI and Combine utilities appledocs. Bump up to 8.0 and iOS 11.0/macOS 10.13 2021-03-01 09:14:41 +09:00
John Estropia
d13b0cfabb update unit tests 2021-02-21 10:59:55 +09:00
John Estropia
d7b852fca4 SwiftUI utilities done (for now) 2021-02-21 10:56:27 +09:00
John Estropia
f2efe175e5 deprecate misleading API for sectionIndexTransformers 2021-02-21 10:17:58 +09:00
John Estropia
8f3a6638d8 Delete long-deprecated CoreStore namespace 2021-02-21 10:16:08 +09:00
John Estropia
f7471f56a4 Prototyping SwiftUI utilities 2021-02-16 09:12:36 +09:00
John Estropia
edd8ba55d8 fix rare duplication of uniqueID values during import when an import candidate is added by a previous insertion block 2021-01-23 16:51:45 +09:00
John Estropia
18aac84335 fix compiler error 2021-01-02 10:36:33 +09:00
John Estropia
c6be892cb0 added .where(combinedByAnd:) and .where(combinedByOr:) to help compiler with long && and || chains 2021-01-02 10:00:23 +09:00
John Estropia
2cd8101987 Implement ObjectRepresentation on ObjectMonitor, ObjectPublisher, and ObjectSnapshot for future APIs 2021-01-02 09:59:15 +09:00
John Estropia
e1aed37da0 avoid using default queue qos 2020-12-26 23:45:11 +09:00
John Estropia
5de5ecee06 give opportunity for faster equating of ObjectSnapshot 2020-12-26 23:44:35 +09:00
John Estropia
9406901b28 WIP: SwiftUI utils 2020-12-26 19:21:46 +09:00
John Estropia
477f478d85 Add missing Where operators (fixes #410) 2020-12-26 14:02:20 +09:00
John Estropia
668b5ad606 Update playground samples to use Field properties instead of old syntax 2020-12-07 14:08:05 +09:00
John Estropia
f985828f3b cleanup 2020-11-17 18:14:23 +09:00
John Estropia
bb3bc940c2 Remove the dataStack SwiftUI environment key since it's prone to initialization issues 2020-11-11 16:56:20 +09:00
John Estropia
2d5bc77219 Merge branch 'master' into minIOS11
# Conflicts:
#	Sources/ListSnapshot.swift
2020-11-11 13:44:58 +09:00
John Estropia
a40df37192 version bump 2020-11-11 13:29:02 +09:00
John Estropia
63b3d25d78 clear warnings 2020-11-11 13:18:11 +09:00
John Estropia
74721b5c12 allow ObjectSnapshot and ObjectPublisher as parameter to Where clauses 2020-10-10 16:55:35 +09:00
John Estropia
f136549b46 prevent creation of ObjectSnapshot if object is already deleted 2020-10-09 20:14:04 +09:00
John Estropia
4ec2b2e311 Optimize ListSnapshot collection implementation 2020-10-05 23:12:17 +09:00
John Estropia
3d82ee18c7 reinclude LegacyDemo in workspace 2020-10-03 14:36:57 +09:00
John Estropia
d6eae8c091 fix podspec 2020-09-19 15:07:27 +09:00
John Estropia
6f8d86cd8f remove xcuserdata 2020-09-19 14:59:14 +09:00
John Estropia
3b6f226389 version bump 2020-09-19 14:44:55 +09:00
John Estropia
228e4e8e1a rename CoreStoreDemo to LegacyDemo 2020-09-19 14:32:43 +09:00
John Estropia
98a42feb95 demo cleanup 2020-09-19 12:38:09 +09:00
John Estropia
2f93ee7591 Migrations demo done 2020-09-17 23:21:41 +09:00
John Estropia
11f5cb9a05 WIP: demo 2020-09-14 09:46:47 +09:00
John Estropia
2c00fc31bc WIP: migrations demo 2020-09-13 14:17:06 +09:00
John Estropia
2bbf6b34ea WIP: migrations demo 2020-09-08 09:09:36 +09:00
John Estropia
8d7f282743 added demo for classic ListMonitor 2020-08-30 20:16:01 +09:00
John Estropia
007da014f8 cleanup 2020-08-30 10:24:10 +09:00
John Estropia
b26e50f777 add version lock to demo 2020-08-29 23:06:12 +09:00
John Estropia
611bc53c9a cleanup 2020-08-29 23:05:07 +09:00
John Estropia
9d36582c10 minor fix 2020-08-29 20:06:00 +09:00
John Estropia
1c735a9228 improve Pokedex demo 2020-08-29 20:02:05 +09:00
John Estropia
1db91fcec3 make demo compilable on Xcode 11 2020-08-27 09:50:12 +09:00
John Estropia
8b3b947406 pokedex demo 2020-08-20 00:39:03 +09:00
John Estropia
2c0cadf2fa WIP 2020-08-19 18:49:08 +09:00
John Estropia
5e536556da fix for SR-13069 2020-08-19 11:01:12 +09:00
John Estropia
d75029f54b WIP 2020-08-19 08:32:18 +09:00
John Estropia
204c4de1f6 use randomElement in unit test 2020-08-18 17:50:00 +09:00
John Estropia
0f3455a4a4 WIP 2020-08-18 12:05:20 +09:00
John Estropia
72f36e7237 WIP 2020-08-17 17:09:41 +09:00
John Estropia
d988daa025 WIP: new demo app 2020-08-17 09:06:25 +09:00
John Estropia
e720504855 Update README.md 2020-06-20 17:37:12 +09:00
John Estropia
ee51c5ad9c fix readme indentations 2020-06-20 16:47:52 +09:00
John Estropia
4ac7df7364 version bump 2020-06-20 13:16:14 +09:00
John Estropia
56f873ccb3 fix readme table of contents 2020-06-20 13:12:11 +09:00
John Estropia
1f90f846f3 readme update 2020-06-20 13:07:10 +09:00
John Estropia
4a97d5a8dc remove persistentstores during DataStack deinitialization to prevent warnings in Unit tests during teardown 2020-05-26 09:43:39 +09:00
John Estropia
0eb9b6393d add unit testst for Field dynamic initializers 2020-05-24 10:54:16 +09:00
John Estropia
56d0ea46ea Implement dynamic initializers for Field properties (fixes #382) 2020-05-23 12:07:16 +09:00
John Estropia
a7568eebdb fix comments 2020-04-15 16:49:45 +09:00
John Estropia
4049e1944a trigger lazy initialization of ObjectPublisher observation after addObserver() (fixes #383) 2020-04-15 16:48:42 +09:00
John Estropia
73b7fcd907 Merge branch 'prototype/propertyWrapperFields' into develop 2020-03-26 02:04:33 +09:00
John Estropia
74c1a97af4 Version bump 2020-03-26 02:04:10 +09:00
John Estropia
97f2a53124 AppleDocs for Field source files 2020-03-26 01:57:32 +09:00
John Estropia
b6db872be0 Merge branch 'prototype/propertyWrapperFields' of github.com:JohnEstropia/CoreStore into prototype/propertyWrapperFields 2020-03-25 19:00:56 +09:00
John Estropia
0d9299f900 WIP: docs 2020-03-25 14:21:49 +09:00
John Estropia
7f928dc684 docs 2020-03-19 14:12:09 +09:00
John Estropia
231e138ab0 performant access of relationship objectIDs for snapshots 2020-02-21 13:51:17 +09:00
John Estropia
361dba58c6 bypass thread checks depending on location of Field call 2020-02-21 11:52:11 +09:00
John Estropia
e1b03b4a89 fix wrong optional configuration in Field.Virtual 2020-02-21 11:20:32 +09:00
John Estropia
0df6c737c1 fix wrong optional configuration in Field.Virtual 2020-02-21 11:17:39 +09:00
John Estropia
12c5aeaaa4 safer casting 2020-02-21 10:36:28 +09:00
John Estropia
dd3fb17dd0 fix runtime issue with Fields on objects with base classes 2020-02-21 10:19:42 +09:00
John Estropia
627a5d4355 add OrderBy utilities for Field.Stored 2020-02-19 22:01:46 +09:00
John Estropia
58629bc1df add missing predicate operator overloads 2020-02-19 13:58:14 +09:00
John Estropia
f925803b93 Create FUNDING.yml 2020-02-19 13:32:57 +09:00
John Estropia
843adf21f7 improved API for custom getters and setters in Field properties 2020-02-18 18:17:52 +09:00
John Estropia
2d1b1e0592 add Field.Coded dynamic lookups for ObjectPublisher and ObjectSnapshot 2020-02-17 18:30:18 +09:00
John Estropia
38e9878c04 Merge branch 'master' into prototype/propertyWrapperFields 2020-02-08 09:47:35 +09:00
John Estropia
8cb8b95c2e fix build for watchOS 2020-02-08 08:49:11 +09:00
John Estropia
8e4e308ccc Merge branch 'prototype/propertyWrapperFields' of github.com:JohnEstropia/CoreStore into prototype/propertyWrapperFields 2020-02-06 09:33:15 +09:00
John Estropia
f0f4049798 renamed Field.Computed to Field.Virtual to distinguish from Field.Derived 2020-02-06 09:33:08 +09:00
John Estropia
c20fe4ac17 add Field.Relationship dynamicMemberLookups 2020-02-05 11:03:57 +09:00
John Estropia
e9c3312612 Fix default encoders for top-level values 2020-01-21 17:03:12 +09:00
John Estropia
92ad895044 Field.Relationship propertyWrapper 2020-01-20 17:13:01 +09:00
John Estropia
bcc2d9def3 Field.Coded implementations for transformable attributes 2020-01-18 16:22:06 +09:00
John Estropia
43f61359da prototype new Fields as propertyWrappers (Swift 5.2 above only) 2020-01-15 18:29:58 +09:00
John Estropia
5e37ee4566 Reorganize properties source files 2020-01-10 17:04:51 +09:00
John Estropia
c544e0cce8 lazily evaluate NSEntityDescription-required fields from CoreStoreObject attributes 2020-01-09 17:00:43 +09:00
John Estropia
f119a3adec add SPM installation instructions to README 2020-01-08 11:21:41 +09:00
John Estropia
c951cb87a3 version bump 2020-01-08 11:03:43 +09:00
John Estropia
08147806a0 explicit exclusion of objc files in package.swift 2020-01-08 11:01:22 +09:00
John Estropia
4beb11519e Deprecation of ObjectiveC shivs 2020-01-08 10:26:27 +09:00
John Estropia
b7ebda4487 Use generic collection types in ListSnapshot mutators 2020-01-05 02:37:42 +09:00
John Estropia
b4489301ac fix SPM spec 2019-12-23 11:53:46 +09:00
John Estropia
c025e5acc6 version bump 2019-12-23 10:11:26 +09:00
John Estropia
57745f36a8 Allow purging of datasource 2019-12-17 21:10:01 +09:00
John Estropia
eef1c99f11 Allow custom views to consume ListSnapshot diffable data 2019-12-17 19:45:53 +09:00
John Estropia
9a19919392 add utility to create ObjectPublisher directly from a DynamicObject using its own context 2019-12-02 12:21:06 +09:00
John Estropia
3e2d62fe67 missed public modifier 2019-12-02 11:53:23 +09:00
John Estropia
6f275eb63a add "updatedItemIdentifiers" utility to ListSnapshot 2019-12-02 10:52:36 +09:00
John Estropia
b12dba4d15 optimizations 2019-11-29 20:09:43 +09:00
John Estropia
4ee1b04523 Support for fetchOffset in ListPublisher, optimize slicing logic 2019-11-18 19:52:57 +09:00
John Estropia
b1decc9853 Force fetchLimit for ListPublisher and ListSnapshot 2019-11-14 20:34:48 +09:00
John Estropia
c2e4c033ef Merge pull request #348 from ntnmrndn/fixWarning
Fix warning
2019-11-05 19:11:51 +09:00
John Estropia
e12223df85 fix casting error 2019-10-29 20:37:08 +09:00
John Estropia
468922d5ed fix casting issues 2019-10-29 20:30:03 +09:00
John Estropia
6b9a4b480b minor 2019-10-29 20:18:14 +09:00
Antoine Marandon
81b482e28b Fix warning 2019-10-29 17:27:25 +09:00
John Estropia
c112a84c0a Add debugDescription implementation for new Publisher and Snapshot types 2019-10-28 19:31:02 +09:00
John Estropia
88ab0b5e15 provide direct conversion from DynamicObject to ObjectSnapshot 2019-10-28 12:03:17 +09:00
John Estropia
717cb75720 Add utility to fetch ObjectPublishers by ObjectID 2019-10-28 11:23:12 +09:00
John Estropia
998938490c Make ObjectPublishers even lighter by lazy-loading observers 2019-10-25 19:16:38 +09:00
John Estropia
f3beca8769 fix compiler error in testcases 2019-10-25 16:17:25 +09:00
John Estropia
4baeb6d922 Fix weak linking of SwiftUI in podspec 2019-10-25 14:35:04 +09:00
John Estropia
98d860aff6 Add unit tests for List and Object Publishers 2019-10-25 14:34:22 +09:00
John Estropia
11a9e3991c changed ListPublisher and ObjectPublisher factory method naming to match ListMonitor and ObjectMonitor naming 2019-10-25 12:43:39 +09:00
John Estropia
f380d9dc25 ObjectSnapshot: allow dynamicMember keyPaths from superclasses 2019-10-25 12:36:13 +09:00
John Estropia
d546ff154f Merge pull request #344 from timfraedrich/patch-1
small correction to documentation
2019-10-23 19:27:33 +09:00
John Estropia
f21597d332 Merge pull request #341 from dmatushkin/develop
Fix for build on iOS with Swift Package Manager
2019-10-23 19:27:01 +09:00
John Estropia
d971c3a2ac README bug 2019-10-22 17:24:54 +09:00
John Estropia
80166a42bb Unify generic labeling 2019-10-22 16:16:47 +09:00
John Estropia
3d8bdf1cf3 Remove references to OSAtomic to silence deprecation warnings 2019-10-22 11:48:09 +09:00
John Estropia
1ddce5aa8d Package.swift update 2019-10-21 22:39:54 +09:00
John Estropia
7a1600fac4 README ok for now 2019-10-21 21:34:45 +09:00
John Estropia
e4e664d8ce README update 2019-10-21 21:24:34 +09:00
John Estropia
145edd5a7d README update 2019-10-21 21:15:46 +09:00
John Estropia
f5fed063ee Docs update 2019-10-20 18:17:31 +09:00
John Estropia
a267395618 WIP: README 2019-10-19 22:17:25 +09:00
John Estropia
326b897b06 WIP: docs 2019-10-19 09:34:31 +09:00
John Estropia
0b18366ab1 Renamed LiveList to ListPublisher and LiveObject to ObjectPublisher. WIP: docs 2019-10-18 19:36:27 +09:00
John Estropia
ddf599ba85 WIP: documentation 2019-10-18 08:19:55 +09:00
John Estropia
6e3e540d0a Improve handling in LiveObject and ObjectSnapshot when objects are deleted 2019-10-17 19:27:03 +09:00
John Estropia
bd066f0cef delete unused files 2019-10-17 16:59:00 +09:00
John Estropia
9764f33086 update demo app 2019-10-17 12:32:47 +09:00
John Estropia
0c19c878c5 LiveList refetch 2019-10-17 11:39:29 +09:00
John Estropia
1b8e517b5a WIP: update demo app 2019-10-17 07:40:15 +09:00
John Estropia
2818a778a4 Revert ObjectMonitor to previous implementation 2019-10-16 19:20:11 +09:00
John Estropia
64a0264354 DiffableDataSource.CollectionView implementation 2019-10-16 14:01:25 +09:00
John Estropia
7932625644 Merge branch 'develop' into datasources 2019-10-16 10:16:13 +09:00
John Estropia
4619fbbec3 WIP: ObjectRepresentable 2019-10-16 08:22:03 +09:00
John Estropia
6b64eb7650 WIP: ObjectRepresentable utilities 2019-10-14 21:36:03 +09:00
John Estropia
f5a165d47d back-portable TableView DiffableDataSource 2019-10-13 11:45:30 +09:00
John Estropia
12c58e3955 improved caching in utility methods 2019-10-12 10:02:00 +09:00
John Estropia
5af0d17de4 remov stateIDs 2019-10-12 07:20:09 +09:00
John Estropia
81dfb8e3e5 WIP: editable datasources 2019-10-11 07:47:49 +09:00
John Estropia
d5114fc4bc WIP 2019-10-08 21:09:34 +09:00
John Estropia
693fc7fbbb Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2019-10-07 10:16:11 +09:00
John Estropia
b073b7e795 swiftUI support done for now 2019-10-06 23:37:04 +09:00
Tim Fraedrich
56d9719984 small correction to documentation
While using some code from the documentation that led to issues I noticed that some parts of it are not accurate anymore, so I corrected a few small things that came to my attention. Maybe it is worth having an even closer look though.
2019-10-04 14:19:14 +00:00
John Estropia
953c9723a8 (WIP) SwiftUI working demo for LiveList<D> 2019-10-04 19:12:32 +09:00
John Estropia
c5a996d5ed WIP: do not use yet 2019-10-04 08:43:04 +09:00
John Estropia
53a83d823e Merge branch 'develop' into datasources 2019-09-22 07:39:18 +09:00
dmatushkin
6d75dcbc32 Fix for build on iOS with Swift Package Manager 2019-09-15 14:57:20 +04:00
John Estropia
0345ee9c94 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2019-09-14 01:40:37 -04:00
John Estropia
4016b5dc83 Merge pull request #331 from jagbryrmiginte/develop
Fixes #328 by specifying platform requirements in Package.swift
2019-09-14 01:34:35 -04:00
John Estropia
64b5e102aa Merge pull request #340 from pushp1989/develop
Added Support for Swift 5
2019-09-14 01:33:51 -04:00
Pushpendra
8e3c44c072 Added Support for Swift 5
Upgraded Xcode build version
Added missing reference of for different targets
2019-09-13 15:27:46 +05:30
John Estropia
12dc32f7e6 Merge branch 'develop' into datasources
# Conflicts:
#	CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/ListObserverDemoViewController.swift
#	CoreStoreTests/DynamicModelTests.swift
#	Sources/BaseDataTransaction+Importing.swift
#	Sources/CoreStoreObject.swift
#	Sources/CustomSchemaMappingProvider.swift
#	Sources/DynamicObject.swift
#	Sources/Functions.swift
#	Sources/ImportableUniqueObject.swift
#	Sources/NSManagedObjectContext+Querying.swift
2019-08-29 17:15:45 +09:00
John Estropia
b4c38caf1e Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2019-08-29 17:03:16 +09:00
John Estropia
266b1a9913 Deprecation of enum CoreStore, reorganize global symbols 2019-08-29 17:03:09 +09:00
John Estropia
1740d168c8 Merge branch 'develop' 2019-08-27 14:38:16 +09:00
John Estropia
d42b397090 version bump 2019-08-27 14:38:05 +09:00
John Estropia
058cc1915b fix optimization issues in release build 2019-08-27 14:21:33 +09:00
John Estropia
02d5bf85ae fix ListMonitor demo for iOS 13 2019-08-20 12:42:34 +09:00
jagbryrmiginte
f0dac2454c Bump SPM package description to 5.0 to resolve compiler error 2019-07-21 12:12:30 +02:00
jagbryrmiginte
d4deed0cf7 Specify minimum deployment target for Swift Package Manager, fixes Issue #328 2019-07-21 12:09:53 +02:00
John Estropia
79655ffde5 added ObjectSnapshot as foundation for datasources API 2019-07-10 08:11:42 +09:00
John Estropia
cf46b45e8e Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2019-07-09 22:53:33 +09:00
John Estropia
ed3d21db77 WIP: reorganization of keypath utilities (in prep for @propertyWrappers) 2019-07-09 14:50:23 +09:00
John Estropia
f16e3593c0 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2019-07-06 23:00:20 +09:00
John Estropia
67bb9340c7 provide way to check if an object has updated properties 2019-07-05 19:07:25 +09:00
John Estropia
5d49bd79f2 Merge pull request #326 from cool8jay/patch-1
Update README code style.
2019-06-29 13:19:14 +09:00
John Estropia
9f397b4337 Prevent crashing when DataStack is deallocated ahead of ListMonitor and child objects 2019-06-10 18:34:15 +09:00
cool8jay
7508d150d6 Update code style.
Update code style.
2019-06-05 08:43:06 +08:00
John Estropia
239db8168d remove artifacts from Carthage 2019-05-19 01:51:46 +09:00
John Estropia
30ab4386bf Merge branch 'develop' 2019-04-27 17:51:12 +09:00
John Estropia
08053ccb15 change protocol inheritance from class to AnyObject (as per recent Swift recommendation) 2019-04-27 17:50:55 +09:00
John Estropia
367cfea8a7 Merge branch 'develop' 2019-04-05 08:36:30 +09:00
John Estropia
5d3b7e3dab version bump 2019-04-05 08:36:09 +09:00
John Estropia
fe7e6e7b84 Fix wrong VersionLock printing on Swift 5 (fixes #311) 2019-04-05 08:29:14 +09:00
John Estropia
b2dba0d6fd update pod version and jazzy docs 2019-03-31 00:29:43 +09:00
John Estropia
6f290213fa update README 2019-03-31 00:05:13 +09:00
John Estropia
0ab52d2f43 converted *Result types to new Swift.Result 2019-03-30 23:58:26 +09:00
John Estropia
bf8a1062e0 deleted obsoleted and deprecated API 2019-03-30 23:56:39 +09:00
John Estropia
0e254867b6 update project for Swift 5 / Xcode 10.2 2019-03-30 23:36:56 +09:00
John Estropia
0376ac6908 bump 2019-02-28 18:57:28 +09:00
John Estropia
b3421888a6 version bump 2019-02-28 18:55:32 +09:00
John Estropia
7b3f4ae0a4 fix compile error 2019-02-28 17:58:17 +09:00
John Estropia
b4e12cc922 restore NSPersistentStore.affectedStores ARC bug workaround 2019-02-28 17:57:34 +09:00
John Estropia
6c282b18af version bump 2019-02-28 13:14:27 +09:00
John Estropia
ebbde8b7b6 minor fix in demo app 2019-02-28 13:13:01 +09:00
John Estropia
a1407e4121 Revert workaround for iOS 10 NSFetchedResultsController (#100) 2019-02-28 13:07:47 +09:00
John Estropia
99b871b97a add missing documentations for Where.Expression, updated playgrounds 2019-02-20 18:47:29 +09:00
John Estropia
1cd3c4fcf4 fix compile error 2019-02-12 18:18:44 +09:00
John Estropia
e09ac9ee00 add macOS playground 2019-02-12 18:05:06 +09:00
John Estropia
4b0d134acb remove swift 5 annotation 2019-02-12 18:03:59 +09:00
John Estropia
eeec3979ee SwiftPM support 2019-02-12 15:48:50 +09:00
John Estropia
5b365c642d add tests for expressio evaluations 2019-02-08 18:42:19 +09:00
John Estropia
635201868a add comparison operators for Where.Expression 2019-02-08 17:16:56 +09:00
John Estropia
db4426e6b9 Swift 5 support. WIP: Support type-safe predicate expressions 2019-02-01 18:32:22 +09:00
John Estropia
41902fee2e fix compiler errors 2019-01-31 16:50:43 +09:00
John Estropia
9239370793 Added reference comment explaining crashes on A12 devices #291 2019-01-29 14:15:01 +09:00
John Estropia
a4d2f326a5 Improve perfomance by bypassing bridging (similar to https://github.com/JohnEstropia/CoreStore/pull/288) 2019-01-28 20:12:18 +09:00
John Estropia
9f54ec26e2 add Where initializer that can accept another Where clause 2019-01-28 20:10:15 +09:00
John Estropia
9425cb56d7 update documentation for -[CSListMonitor refetch:] to reflect actual behavior 2019-01-28 19:04:46 +09:00
John Estropia
1de56d2776 add missing From.orderBy(_:) overloads 2019-01-25 17:30:11 +09:00
John Estropia
b3261ea930 Update README.md 2019-01-24 16:12:12 +09:00
John Estropia
88dd7aef72 updated README 2019-01-24 15:32:54 +09:00
John Estropia
2863605d84 silence deprecation internal warnings 2019-01-23 12:25:52 +09:00
John Estropia
94d9116299 pod bump 2019-01-23 10:56:10 +09:00
John Estropia
57ddbbd515 make some test cases validate specific error codes from thrown errors 2019-01-23 10:55:58 +09:00
John Estropia
78954b9d78 version bump 2019-01-22 16:41:58 +09:00
John Estropia
4eb06c9858 Merge branch 'throwables' into develop 2019-01-22 16:38:57 +09:00
John Estropia
0d634c1dcc add missing MARKs 2019-01-22 16:38:17 +09:00
John Estropia
84f3740ea1 fix unit test warnings 2019-01-18 17:30:54 +09:00
John Estropia
6dc48b6af7 Add docs for new throwing methods 2019-01-17 18:43:10 +09:00
John Estropia
09ce2816bf Merge branch 'develop' into throwables 2019-01-16 17:03:49 +09:00
John Estropia
62e962eebe Merge pull request #301 from ianbytchek/develop
Resolve source entity and managed object attributes by name
2019-01-16 17:01:48 +09:00
John Estropia
682472c1bd fetches, queries, and deletes are now throwable methods 2019-01-15 20:40:15 +09:00
Ian Bytchek
46ab70b839 Update TravisCI base image to Xcode 10
Replace deprecated build matrix configurations with newer alternatives.
2019-01-13 06:24:04 +00:00
Ian Bytchek
ac8304f977 Resolve source entity and managed object attributes by name
Addresses #300 – see it for details. Also improves the use of whitespace consistency across the `CustomSchemaMappingProvider.swift` and uses method names for `cs_resolve…` over `cs_resolved…` for better alignment with [Swift API Design Guidelines](https://swift.org/documentation/api-design-guidelines).
2019-01-13 05:41:34 +00:00
John Estropia
5777831565 WIP: make fetching methods throwable 2019-01-11 19:52:12 +09:00
John Estropia
42d1f41939 Provide more context when failing to search for mapping models #299 2019-01-11 19:48:35 +09:00
John Estropia
8c30ec3a3d minor fixes on Playgrounds and Demo app 2019-01-09 11:59:06 +09:00
John Estropia
237a1b648e Assert on reserved property names 2019-01-09 11:58:37 +09:00
John Estropia
614f1572c2 print PartialObjects 2018-12-26 22:35:28 +08:00
John Estropia
a48f16aa8c add Jazzy docs 2018-12-19 16:27:05 +09:00
John Estropia
cdbadae002 added comments to playground 2018-12-18 18:44:47 +09:00
John Estropia
4a28a39df6 removed long-standing workaround for NSFetchedResultsController bugs since they seem to be fixed 2018-12-18 18:43:36 +09:00
John Estropia
5febf2542d added playgrounds just to show off 2018-12-14 19:28:55 +09:00
John Estropia
c21ab11a41 format header comment 2018-12-14 18:21:41 +09:00
John Estropia
10cd18dbf0 prototype for CoreStoreObject property observers (a.k.a. KVO) 2018-12-14 18:20:42 +09:00
John Estropia
8409a13289 Merge pull request #288 from ruslanskorb/list-monitor-number-of-objects-performance
[ListMonitor] Fix performance of `numberOfObjects()`.
2018-12-06 18:53:06 +09:00
Ruslan Skorb
a9a73fa5c4 [ListMonitor] [numberOfObjects()] Return count of fetchedObjects.
Casting `fetchedObjects` to `NSArray?` has better performance.
https://github.com/JohnEstropia/CoreStore/pull/288
2018-12-06 10:56:30 +02:00
John Estropia
82cae2e11e Merge pull request #292 from eliseo-juan/patch-1
Fix documentation
2018-12-06 10:54:50 +09:00
John Estropia
42caee2418 Merge pull request #287 from ruslanskorb/list-monitor-subscript-performance
[ListMonitor] Fix performance of `subscript(safeSectionIndex:safeItemIndex:)`.
2018-12-06 10:54:12 +09:00
Eliseo Juan Quintanilla
1dea1d0d06 Fix documentation
Changed attribtue to attribute
2018-12-05 10:09:05 +01:00
John Estropia
d344b9d878 minimum deployment version bumped to iOS 10, macOS 10.12, tvOS 10, watchOS 3. Deprecated iCloud Storage 2018-12-05 17:31:16 +09:00
John Estropia
95c1ce52cc Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-12-05 16:17:03 +09:00
John Estropia
cc346816d6 Added new error for cases when addStorageAndWait() is used with .allowSynchronousLightweightMigration but migrations are only allowed asynchronously (related to #277) 2018-12-05 16:15:20 +09:00
John Estropia
f14b561c33 Merge pull request #275 from DmitrijMaz/fix_queueing
Fix queue validation for UnsafeDataTransaction
2018-12-05 11:02:47 +09:00
Ruslan Skorb
6f655951aa [ListMonitor] [numberOfObjects()] Calculate the number of objects in all sections by summing the number of objects stored in NSFetchedResultsSectionInfo.
There is a performance problem in Swift when calling `count` method on an array with a large number of fetched objects. It requires casting the array between Objective-C and Swift, that is pretty slow.
2018-11-24 16:24:14 +02:00
Ruslan Skorb
ff8fbae568 [ListMonitor] [subscript(safeSectionIndex:safeItemIndex:)] Use subscript(indexPath:) after the validation of sectionIndex and itemIndex to get an object.
There is a performance problem in Swift when getting an object from the Objective-C array with a large number of objects using subscript. It requires casting the array between Objective-C and Swift, that is pretty slow.
2018-11-24 16:23:36 +02:00
Dmitry Mazurenko
4d4b02d076 Fix queue validation for UnsafeDataTransaction 2018-10-10 16:48:04 +03:00
John Estropia
06c0981ded debug string for CoreStoreObject 2018-09-24 00:49:53 +09:00
John Estropia
20d581d536 version bump 2018-09-19 18:48:45 +09:00
John Estropia
45e110755d deleted unnecessary Equatable and Hashable custom implementations 2018-09-19 11:06:19 +09:00
John Estropia
ab40532801 fix issue with early-deallocated CoreStoreObjects 2018-09-18 23:50:14 +09:00
John Estropia
40f458a09c Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-09-15 12:56:21 +09:00
John Estropia
1ad233ca9d Swift 4.2 support 2018-09-15 12:56:08 +09:00
John Estropia
3a8e394272 Merge pull request #269 from congbach/develop
Fixed bug where ListObjectObserver didUpdateObject was not called on …
2018-09-10 19:30:06 +09:00
Ken Bach
1f54daa528 Fixed bug where ListObjectObserver.didUpdateObject was not called on watchos. 2018-08-21 22:47:54 +01:00
John Estropia
f25879b6fe fix compile error on tvOS and watchOS 2018-08-09 21:04:09 +09:00
John Estropia
8fa3109e91 version bump 2018-08-09 20:45:46 +09:00
John Estropia
808e8ff97a stabilize NSProgress when lightweight migration falls back to InferredMappingModel 2018-08-09 18:18:21 +09:00
John Estropia
30685d4355 Use InferredMappingModel in case lightweight migration fails for some reason 2018-08-09 02:09:54 +09:00
John Estropia
7152962026 revert 2018-08-09 01:39:16 +09:00
John Estropia
91735e38d1 Fix issue where CoreStoreObjects nested in a type is mismatching classnames before migration 2018-08-08 23:52:47 +09:00
John Estropia
333a50ad9e Merge pull request #256 from vGubriienko/demo-fix
Fixed issue with brightness observing in the Demo
2018-08-03 17:44:40 +09:00
John Rommel Estropia
b7a602fc67 iOS 11 Core Data changes 2018-07-29 23:33:51 +09:00
Viktor Gubriienko
2ff7ecef96 Fixed issue with brightness observing in the Demo 2018-06-12 17:53:00 +03:00
John Rommel Estropia
e3f9139304 version bump 2018-06-10 11:52:47 +09:00
John Rommel Estropia
4aa461872f specify swift version in podspec 2018-06-10 11:47:03 +09:00
John Rommel Estropia
3d43314076 update readme 2018-04-14 09:05:13 +09:00
John Rommel Estropia
7b1075b759 support compound indexes and unique constraints on CoreStore properties 2018-03-17 23:56:42 +09:00
John Rommel Estropia
0c29e07ddb support allowsExternalBinaryDataStorage option on Transformable CoreStoreObject properties 2018-03-17 23:56:01 +09:00
John Rommel Estropia
ce91cf22f9 Swift 4.1 support 2018-03-17 23:53:24 +09:00
John Rommel Estropia
2dd033c002 Merge branch 'develop' into prototype/Swift_4_1 2018-03-10 21:09:29 +09:00
John Rommel Estropia
c7fcba112e Fix bug where ListMonitor sectionIndexTitles are not updated on refetch (fixes #218) 2018-03-10 21:09:18 +09:00
John Rommel Estropia
c8b1c4358f Fix bug where ListMonitor sectionIndexTitles are not updated on refetch (fixes #218) 2018-03-10 21:08:40 +09:00
John Rommel Estropia
5431e2e974 Swift 4.1 support 2018-03-10 21:07:53 +09:00
John Rommel Estropia
83e6082c56 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-01-07 23:25:11 +09:00
John Rommel Estropia
c7bdbbde57 convert value to native type before formatting predicates 2018-01-07 21:06:35 +09:00
John Estropia
abf15c8aa8 Merge pull request #232 from kf99916/external-storage-migration
External storage migration
2018-01-06 17:48:38 +09:00
Zheng-Xiang Ke
d9db7e4a82 Typo 2018-01-06 15:00:53 +08:00
John Estropia
65dbc22ddd Merge pull request #231 from doodzik/patch-1
Fix syntax error in readme
2018-01-06 15:11:48 +09:00
Zheng-Xiang Ke
51961dd737 Migrate external storage 2018-01-06 10:22:44 +08:00
Frederik Dudzik
18a7055cdf Fix syntax error 2018-01-05 21:16:04 +01:00
John Rommel Estropia
4b9fddad6a Merge branch 'develop' 2017-12-29 01:09:07 +09:00
John Rommel Estropia
fbe7bd7bf8 update podfile 2017-12-29 00:53:48 +09:00
John Rommel Estropia
15edabdbb5 changed keyPath string utility to use String initializer 2017-12-29 00:05:11 +09:00
John Rommel Estropia
f447bcfb95 Merge branch 'develop' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/DataStack+Migration.swift
#	Sources/Info.plist
2017-11-19 15:35:29 +09:00
John Rommel Estropia
15e5e4fdf6 delete shm file after converting to DELETE journal mode 2017-11-19 15:34:09 +09:00
John Rommel Estropia
583c6b7249 minor code cleanup 2017-11-19 13:49:21 +09:00
John Rommel Estropia
18b933957e version bump 2017-11-16 02:28:18 +09:00
John Rommel Estropia
2c7039232e merge sqlite journal files before migration 2017-11-16 02:27:06 +09:00
John Rommel Estropia
d3b3b5ff4a added fake progress for lightweight migrations 2017-11-16 02:26:56 +09:00
John Rommel Estropia
d90e8d1303 force true lightweight migration 2017-11-16 02:26:44 +09:00
John Rommel Estropia
b55dd13dff merge sqlite journal files before migration 2017-11-15 23:50:10 +09:00
John Rommel Estropia
66dd5b6f27 added fake progress for lightweight migrations 2017-11-13 02:44:26 +09:00
John Estropia
49c4b770eb WIP: Readme 2017-11-10 19:19:48 +09:00
John Rommel Estropia
662aaa1e75 force true lightweight migration 2017-11-10 02:48:37 +09:00
John Rommel Estropia
dd4e47d7f9 revert null overloads, remove optional objectIDs as condition 2017-11-09 23:26:53 +09:00
John Estropia
9ea5073bc8 Merge branch 'master' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-11-09 19:52:29 +09:00
John Estropia
e314db8f56 version bump 2017-11-09 19:45:21 +09:00
John Estropia
48d936d068 Fix regression for ARC bugfix (fixes #221) 2017-11-09 19:44:27 +09:00
John Estropia
b2ff8a15ef add query overloads to == so comparison with nil don't confuse the compiler 2017-11-09 19:27:56 +09:00
John Estropia
8a4d1cd7c6 fix demo app warnings 2017-11-09 19:27:05 +09:00
John Rommel Estropia
8ce26c213d more source docs, deprecated some Where clause utilities 2017-11-04 10:37:54 +09:00
John Estropia
f3816b9abf update for Xcode 9.1 2017-11-01 19:49:42 +09:00
John Estropia
21961780d4 force dynamic typing on DynamicObject.Type to mitigate optimization issues 2017-11-01 19:38:38 +09:00
John Rommel Estropia
305e2b61a0 fix compile errors for Xcode 9.1 beta 2017-11-01 19:37:53 +09:00
John Estropia
0430f66240 force dynamic typing on DynamicObject.Type to mitigate optimization issues 2017-11-01 11:33:41 +09:00
John Estropia
65772edd00 Merge pull request #208 from volodg/prototype/Swift_4_0
(Xcode 9.1) fix compile error:
2017-10-29 18:55:13 +09:00
John Rommel Estropia
02d7870d75 fix compile errors for Xcode 9.1 beta 2017-10-29 15:20:58 +09:00
John Rommel Estropia
aca1709e13 WIP: documentation 2017-10-29 15:06:57 +09:00
John Rommel Estropia
b6ee0b014f WIP: documentations 2017-10-24 00:31:27 +09:00
John Estropia
e37186da73 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-17 13:42:04 +09:00
John Estropia
588fa35c84 version bump 2017-10-17 13:39:57 +09:00
John Estropia
f6614cda66 Merge branch 'develop' 2017-10-17 13:39:20 +09:00
John Estropia
639574d8c2 remove inline casts because optimized builds seem to trip on them 2017-10-17 13:38:25 +09:00
John Rommel Estropia
094703155c Merge branch 'master' into prototype/Swift_4_0
# Conflicts:
#	.swift-version
2017-10-13 08:14:20 +09:00
John Rommel Estropia
6dd254e713 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-13 08:10:56 +09:00
John Rommel Estropia
204025721c version bump 2017-10-13 08:10:26 +09:00
John Rommel Estropia
27ffc1d225 Merge branch 'develop'
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-13 08:01:30 +09:00
John Rommel Estropia
ba6f0c39d5 swift version 3.2 2017-10-13 08:00:39 +09:00
John Rommel Estropia
ab2eac8f6c Swift 3.2 README update 2017-10-13 07:58:37 +09:00
John Rommel Estropia
f460a0b30f CI: test demo app 2017-10-12 01:10:08 +09:00
John Rommel Estropia
50bc3ace06 travis 2017-10-12 00:02:39 +09:00
John Rommel Estropia
d2ddf2002f version update 2017-10-11 22:40:27 +09:00
John Rommel Estropia
b4117eeb02 updated documentation (fixes #198) 2017-10-11 07:50:24 +09:00
Vladimir
106275b2dd fix compile error:
inheritance from 'AnyObject'
2017-10-07 12:21:27 +08:00
John Rommel Estropia
08d9298be0 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/OrderBy.swift
2017-10-07 01:13:30 +09:00
John Rommel Estropia
ff0c4d94fc Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-10-07 01:10:28 +09:00
John Rommel Estropia
50e50c0613 Merge branch 'develop' into prototype/Swift_3_2 2017-10-07 01:07:09 +09:00
John Rommel Estropia
5c8a0e425b version bump 2017-10-07 00:59:37 +09:00
John Rommel Estropia
03b71caf7e Merge branch 'develop' 2017-10-07 00:58:04 +09:00
John Rommel Estropia
7ff29d6086 version bump 2017-10-07 00:57:41 +09:00
John Rommel Estropia
8d86425875 always create subclass type from cs_rawObject 2017-10-07 00:56:19 +09:00
John Estropia
97242d9726 added type-erasers for CoreStoreObject property containers 2017-10-02 12:00:45 +09:00
John Estropia
780ff4e60b fix compile errors 2017-10-02 11:10:28 +09:00
John Estropia
11743dfb5f oops 2017-10-02 11:08:44 +09:00
John Estropia
9eaf85388c relax generic type requirements for some Where utilities 2017-10-02 10:33:59 +09:00
John Rommel Estropia
06635c9d2f orderby utilities 2017-10-02 08:04:28 +09:00
John Rommel Estropia
1d2eef7894 revert 2017-10-01 01:01:10 +09:00
John Rommel Estropia
85ed815ec2 WIP: more chain clause builder utilities 2017-10-01 00:45:21 +09:00
John Estropia
096e5493a6 WIP: protocol cleanup 2017-09-29 20:33:10 +09:00
John Estropia
0aa8c03424 Merge pull request #205 from jannon/case-insensitive-orderby
add case-insensitive sortkeys
2017-09-29 19:38:36 +09:00
John Estropia
4ead3c34dd delete errant operator 2017-09-26 11:59:28 +09:00
John Rommel Estropia
645034dde5 keyPath utilities for SectionBy clauses 2017-09-24 10:38:17 +09:00
John Rommel Estropia
85706a3c57 version bump 2017-09-22 23:43:19 +09:00
John Rommel Estropia
c5ae4606b9 move cocoapods.yml 2017-09-22 23:41:07 +09:00
John Rommel Estropia
fa682215c5 version bump 2017-09-22 23:26:15 +09:00
John Rommel Estropia
e814733ae9 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/DynamicObject.swift
2017-09-22 23:20:16 +09:00
John Rommel Estropia
e2236698fa Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-09-22 23:18:38 +09:00
John Rommel Estropia
be5da632b3 fix segmentation fault 2017-09-22 23:18:25 +09:00
John Estropia
dc73cd6dd9 added a yml file for pod try (#200) 2017-09-22 15:48:02 +09:00
John Rommel Estropia
7beb3bec75 rename methods 2017-09-22 08:02:13 +09:00
Jannon Frank
53100b202d add case-insensitive sortkeys 2017-09-21 11:38:29 -07:00
John Rommel Estropia
cc84b1f8bd minor 2017-09-22 01:00:03 +09:00
John Rommel Estropia
474f52ed2b alow nil comparison for relationship keypaths 2017-09-22 00:30:02 +09:00
John Rommel Estropia
16225fc4c6 allow optionals in relationship keyPaths 2017-09-22 00:20:55 +09:00
John Rommel Estropia
03bb7619da added queryBuilder utilities for clause sequences 2017-09-22 00:08:01 +09:00
John Rommel Estropia
1bfb7451c3 keyPath utilities for Select queries 2017-09-21 07:56:02 +09:00
John Rommel Estropia
3e082d5ed4 queryBuilders for list monitors 2017-09-20 00:45:38 +09:00
John Rommel Estropia
e45d67252c CoreStore querying utilities 2017-09-20 00:24:03 +09:00
John Rommel Estropia
3d427c29c4 added required settings 2017-09-20 00:09:57 +09:00
John Rommel Estropia
1068517b94 Merge branch 'prototype/queryBuilders' of github.com:JohnEstropia/CoreStore into prototype/queryBuilders 2017-09-20 00:02:36 +09:00
John Estropia
0d23ce1598 fix Demo app compiler errors 2017-09-19 16:22:59 +09:00
John Estropia
fd1ce20863 set swift version 2017-09-19 16:04:26 +09:00
John Estropia
2c5fa63f40 revert 2017-09-19 15:55:51 +09:00
John Estropia
78e43a37a5 fix OSX compiler errors 2017-09-19 15:54:15 +09:00
John Rommel Estropia
fde85a9743 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-09-17 01:15:55 +09:00
John Rommel Estropia
dbbc0adae5 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-09-17 01:10:11 +09:00
John Rommel Estropia
2a62770552 Merge branch 'develop' into prototype/Swift_3_2 2017-09-10 12:31:30 +09:00
John Rommel Estropia
f436b26e8e allow compound keypaths in Select terms 2017-09-08 01:28:24 +09:00
John Rommel Estropia
c566226747 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-31 23:50:12 +09:00
John Rommel Estropia
cd405e038e updated demo app 2017-08-31 23:00:17 +09:00
John Estropia
92a37053b0 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-31 18:33:28 +09:00
John Estropia
0b57cff27d Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/DynamicSchema+Convenience.swift
2017-08-31 18:33:12 +09:00
John Estropia
3ebc44b546 optimize redundant casting in printCoreStoreSchema() 2017-08-31 18:28:23 +09:00
John Estropia
68f1027ba7 fix code misuse in readme 2017-08-31 17:55:10 +09:00
John Rommel Estropia
005729be85 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-26 14:29:16 +09:00
John Estropia
8bac4aa901 Fixed Xcode 9 beta 6 errors 2017-08-24 10:11:12 +09:00
John Estropia
da170c7e51 Fixed Xcode 9 beta 6 errors 2017-08-23 18:40:06 +09:00
John Estropia
211e69023e version bump 2017-08-23 12:59:36 +09:00
John Rommel Estropia
2912dcf010 iOS 11 fixed the NSFetchRequest.affectedStores bug 2017-08-23 12:55:02 +09:00
John Rommel Estropia
3e00a3da06 fix demo app errors 2017-08-17 09:24:33 +09:00
John Rommel Estropia
a33e248828 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/NSManagedObjectContext+Querying.swift
2017-08-16 21:09:09 +09:00
John Rommel Estropia
75e14fbbed Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	Sources/NSManagedObjectContext+Querying.swift
2017-08-16 21:08:33 +09:00
John Rommel Estropia
9922deac4d Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/AttributeProtocol.swift
#	Sources/DynamicSchema+Convenience.swift
#	Sources/ImportableAttributeType.swift
#	Sources/Relationship.swift
#	Sources/RelationshipProtocol.swift
#	Sources/Transformable.swift
#	Sources/Value.swift
2017-08-16 21:07:34 +09:00
John Rommel Estropia
86be046c9f updated podspec 2017-08-16 20:43:10 +09:00
John Rommel Estropia
0f10bc3349 version bump 2017-08-16 20:26:22 +09:00
John Rommel Estropia
9685f0aef2 #191 2017-08-16 20:21:26 +09:00
John Estropia
1e51000155 Merge pull request #191 from sidmani/prototype/Swift_4_0
Corrected type-checking in fetchExisting to preserve input type
2017-08-16 20:20:23 +09:00
John Rommel Estropia
3bd459bb1a updated docs 2017-08-16 20:09:09 +09:00
Sid Mani
c89bc3c227 Corrected type-checking in fetchExisting to preserve input type 2017-08-16 00:36:06 -07:00
John Rommel Estropia
0f405a50aa WIP: KeyPath utilities for all clauses 2017-08-10 00:42:29 +09:00
John Estropia
f5e1643ef7 minor cleanup 2017-08-10 00:10:15 +09:00
John Rommel Estropia
f62137fb58 rename file 2017-08-10 00:10:08 +09:00
John Rommel Estropia
37fbedd799 WIP: keypath utilities for all raw clauses 2017-08-09 08:11:41 +09:00
John Rommel Estropia
28b43f33fa Value.Required now requires an "initial:" parameter. For previous CoreStoreObject users, use the appropriate empty value for your existing properties (0 for numeric types, false for Bool, "" for String) 2017-08-08 18:36:25 +09:00
John Rommel Estropia
81a72f29ea Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-08 08:02:17 +09:00
John Rommel Estropia
f7aaf4fb2a Fix compile errors for Xcode 9 beta 5 2017-08-08 08:02:05 +09:00
John Rommel Estropia
a52acf2ebd Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-08 07:56:32 +09:00
John Rommel Estropia
74c64619c3 Fix compile error for Xcode 9 beta 5 2017-08-08 07:56:21 +09:00
John Rommel Estropia
4a5bc6450b complete query utilities 2017-08-08 07:36:52 +09:00
John Rommel Estropia
fe69e7c6c4 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	CoreStore.xcodeproj/project.pbxproj
#	Sources/Relationship.swift
#	Sources/Value.swift
2017-08-05 23:02:00 +09:00
John Rommel Estropia
ccf7c62aad Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-05 08:25:49 +09:00
John Rommel Estropia
f36cb8af63 iOS 11 fixed the NSFetchRequest.affectedStores bug 2017-08-05 08:25:28 +09:00
John Rommel Estropia
10ccadd96c update demo app 2017-08-05 08:25:03 +09:00
John Rommel Estropia
5c0e78bd53 Deleted EmptyableAttributeType and require "initial" parameter for Value.Required 2017-08-05 00:03:17 +09:00
John Rommel Estropia
8a09688117 Merge branch 'develop' into prototype/Swift_3_2 2017-07-15 21:30:05 +09:00
John Estropia
a366bcf1a3 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2017-07-11 15:47:20 +09:00
John Rommel Estropia
fcd4be9011 WIP: chained queries for section monitors 2017-07-10 08:23:59 +09:00
John Rommel Estropia
535eb76adc WIP: query chains! 2017-07-09 10:44:53 +09:00
John Rommel Estropia
c6e68ac24f reset transactions' context on deinit to break reference cycles in unsafed many-to-many relationships 2017-07-05 23:32:45 +09:00
John Rommel Estropia
aff966aac9 WIP: Query builders 2017-07-05 08:45:10 +09:00
John Rommel Estropia
32743b3aee Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-07-04 23:16:49 +09:00
John Rommel Estropia
a20ad87583 Merge branch 'develop' into prototype/Swift_3_2 2017-07-04 23:14:06 +09:00
John Estropia
a11915db12 minor cleanup 2017-07-04 12:21:46 +09:00
John Rommel Estropia
961f39a806 add internal utilities to force checkpoint operations on SQLite 2017-07-01 17:05:10 +09:00
John Rommel Estropia
3096cb784c add internal utilities to force checkpoint operations on SQLite 2017-07-01 16:45:11 +09:00
John Rommel Estropia
809aa4ff96 allow querying file size on SQLiteStore 2017-07-01 11:50:23 +09:00
John Estropia
8d926d25ec Merge pull request #177 from blender/feature/optional-where-chaining
Add optional && and || operators to Where clause
2017-06-28 13:32:16 +09:00
Tommaso Piazza
790454f514 Add optional && and || operators to Where clause 2017-06-27 13:58:16 +02:00
John Rommel Estropia
9a38707c58 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-26 00:36:07 +09:00
John Rommel Estropia
fb7e2f7f7f Merge branch 'develop' into prototype/Swift_3_2 2017-06-26 00:34:32 +09:00
John Rommel Estropia
f72efc80b2 added utilities for combining Where arrays and OrderBy arrays 2017-06-24 17:42:56 +09:00
John Estropia
fcda5399da Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-23 17:58:49 +09:00
John Estropia
fd3a9b00ec fix FRC breaking again for iOS 8 2017-06-23 17:58:34 +09:00
John Estropia
f56c37f9ee Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-23 12:43:20 +09:00
John Estropia
5f5000218a Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift
#	Sources/Value.swift
2017-06-23 12:43:03 +09:00
John Estropia
e8eb309d82 Added source docs on usage of custom getters and setters for CoreStoreObject properties (Value.Required, etc) 2017-06-20 20:32:27 +09:00
John Rommel Estropia
d0c3203e63 force reset contexts after autocommit 2017-06-17 21:50:21 +09:00
John Rommel Estropia
f5b3901caa fix tests and demo app 2017-06-17 02:13:54 +09:00
John Rommel Estropia
1a99fea820 complete PartialObject utilities 2017-06-17 01:55:36 +09:00
John Rommel Estropia
195b60615b added missing utilities 2017-06-16 01:42:09 +09:00
John Rommel Estropia
2c394965b8 remove direct access to CoreStoreObject.primitiveValues and replace PartialObject<O> 2017-06-16 01:02:23 +09:00
John Rommel Estropia
746d697691 WIP: new PartialObject to act as faster KVC wrappers when implementing custom getters and setters for CoreStoreObject 2017-06-15 08:27:08 +09:00
John Estropia
5689158b43 version bump 2017-06-14 21:50:58 +09:00
John Estropia
6fcdf3d011 fix logger demo 2017-06-14 17:43:34 +09:00
John Estropia
e26573c18e converted the Demo app's observer demo to use CoreStoreObject instead of NSManagedObject 2017-06-14 17:39:57 +09:00
John Estropia
801cf8d9f0 Fixed ListMonitor bug for CoreStoreObjects where ListObservers don't get update notifications 2017-06-14 17:37:46 +09:00
John Rommel Estropia
eced8f2e93 fixed compile error on release mode 2017-06-12 22:39:06 +09:00
John Rommel Estropia
3b735d07ec fix merge compile errors 2017-06-11 09:33:25 +09:00
John Rommel Estropia
5eb5476e3a Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-11 09:17:03 +09:00
John Rommel Estropia
6a42a0054e Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/CoreStoreManagedObject.swift
#	Sources/CoreStoreSchema.swift
#	Sources/NSEntityDescription+DynamicModel.swift
#	Sources/Value.swift
2017-06-11 09:16:34 +09:00
John Rommel Estropia
8c437e19b8 version bump 2017-06-10 23:19:02 +09:00
John Rommel Estropia
9cd3b6c879 code cleanup 2017-06-10 22:13:32 +09:00
John Rommel Estropia
fe135acbec Improve CoreStoreObjects KVO behavior 2017-06-10 21:02:36 +09:00
John Estropia
997c5bdcfa uniquify subclass names across model versions 2017-06-09 12:47:22 +09:00
John Estropia
23e12c4539 add constraints to Value.Optional and Value.Required native types 2017-06-09 11:30:09 +09:00
John Estropia
ca9798be14 add constraints to Value.Optional and Value.Required native types 2017-06-09 11:29:51 +09:00
John Estropia
6e01a58c85 Swift 4 support 2017-06-09 11:25:28 +09:00
John Estropia
f618617053 work around issue that crashes the Swift 3.2 compiler (fixes #171) 2017-06-08 20:18:50 +09:00
John Rommel Estropia
49b8b9c372 Merge branch 'master' into prototype/Swift_3_2 2017-06-08 08:10:59 +09:00
John Rommel Estropia
129f975d96 version bump 2017-06-08 01:17:39 +09:00
John Rommel Estropia
a2e463e58c Merge branch 'prototype/customMigrationTest' of github.com:JohnEstropia/CoreStore into prototype/customMigrationTest 2017-06-08 01:07:00 +09:00
John Rommel Estropia
5fd50f0e15 fix migration for CoreStoreObject relationships 2017-06-08 01:06:51 +09:00
John Estropia
7f9a915d71 WIP: Swift 3.2 2017-06-07 20:07:43 +09:00
John Estropia
0a81736b7a Merge branch 'develop' into prototype/customMigrationTest 2017-06-07 12:31:42 +09:00
John Estropia
f9b6dd0c6a fix bug when using ObjectMonitor with CoreStoreObjects 2017-06-06 17:40:29 +09:00
John Rommel Estropia
0354401b56 WIP: bugfix for CustomSchemaMappingProvider relationship migration bug 2017-06-06 08:39:59 +09:00
John Rommel Estropia
0304067beb fix ToManyOrdered and ToManyUnordered enumeration crash 2017-06-06 00:49:16 +09:00
John Rommel Estropia
ddd83da434 add Where comparison operators for optional values 2017-06-05 23:09:19 +09:00
John Estropia
fc7df671de Fixes https://bugs.swift.org/browse/SR-4981 2017-06-05 12:45:35 +09:00
John Rommel Estropia
5fde9030c7 use stronger namespace for CoreStoreObject's internal managed object type 2017-06-05 08:03:37 +09:00
John Rommel Estropia
d7b07b3f00 Added alternative way to set keyPathsForValuesAffectingValue(forKey:) for CoreStoreObjects 2017-06-05 01:30:26 +09:00
John Rommel Estropia
ddd1ffb29f added ~= operation to create Where clauses for value arrays 2017-06-03 08:51:52 +09:00
John Rommel Estropia
98094000bb Merge branch 'master' into develop 2017-06-02 23:10:31 +09:00
John Estropia
d5026ef996 Merge branch 'temp/develop' into develop 2017-06-02 19:35:01 +09:00
John Estropia
2cd913b9dd added more utilities for CoreStoreObject meta 2017-06-02 19:34:54 +09:00
John Estropia
ad9520abbc Update README.md 2017-06-02 13:24:15 +09:00
John Estropia
c0fc57d10c Update README.md 2017-06-02 11:34:04 +09:00
John Estropia
0cf4d303e4 Added README sample on how to version CoreStoreObjects 2017-06-02 11:32:48 +09:00
John Rommel Estropia
6de397958a fix demo app warnings 2017-06-02 02:06:47 +09:00
John Rommel Estropia
55292a84dc made mapping modell providers public 2017-06-02 02:03:41 +09:00
John Estropia
981b560d53 test travis ci 2017-05-30 11:14:57 +09:00
John Estropia
c4c4dd55cd test travis build 2017-05-30 11:06:30 +09:00
John Rommel Estropia
1ddbe20c86 Updated README, fixed demo app, and bumped to 4.0.1 2017-05-28 11:37:40 +09:00
John Rommel Estropia
da9e8c1550 disallow "empty" default values on some ImportableAttributeTypes 2017-05-28 10:50:25 +09:00
John Estropia
ef0937fec4 make unit tests happy 2017-05-24 12:15:55 +09:00
John Estropia
35885b40de README done! Welcome to CoreStore 4.0! 2017-05-24 12:05:34 +09:00
John Rommel Estropia
d669569196 WIP: readme 2017-05-24 00:37:32 +09:00
John Rommel Estropia
ae919ff3c8 WIP: readme 2017-05-24 00:35:25 +09:00
John Rommel Estropia
1a7a4690d1 WIP: readme 2017-05-24 00:33:43 +09:00
John Rommel Estropia
b9b96d1a35 WIP: Updating README and other docs. Some minor fixes 2017-05-22 01:27:38 +09:00
John Rommel Estropia
da3a9590ac accept optionals in setValue 2017-05-21 09:38:56 +09:00
John Rommel Estropia
6b3d75bea1 fix fixits 2017-05-21 09:29:34 +09:00
John Rommel Estropia
d44721fef0 fix xcode hints 2017-05-21 09:11:34 +09:00
John Rommel Estropia
3f268e8376 added NSManagedObject.setValue(_:forKvcKey:willSetValue:didSetValue:) 2017-05-21 09:06:29 +09:00
John Rommel Estropia
303fea4ebe fix warnings 2017-05-21 08:51:38 +09:00
John Estropia
77173cdad0 minor fix 2017-05-18 21:10:43 +09:00
John Estropia
1e24a7d739 ListObserver's listMonitorDidChange(_:) and listMonitorDidRefetch(_:) handlers are now required. 2017-05-18 12:59:58 +09:00
John Estropia
a3b33bedb8 added more migration error types 2017-05-18 12:59:02 +09:00
John Estropia
eaf7544c50 fix error when CoreStoreObject types have deep namespaces 2017-05-17 15:55:33 +09:00
John Estropia
67863120e0 WIP: readme 2017-05-15 11:03:21 +09:00
John Estropia
1b0e305d9a beta bump 2017-05-15 10:23:55 +09:00
John Rommel Estropia
91fda01071 WIP: readme 2017-05-15 08:51:31 +09:00
845 changed files with 608368 additions and 25955 deletions

2
.cocoapods.yml Normal file
View File

@@ -0,0 +1,2 @@
try:
project: 'CoreStore.xcworkspace'

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [JohnEstropia]

7
.gitignore vendored
View File

@@ -7,3 +7,10 @@ CoreStore.xcworkspace/xcuserdata
.DS_Store .DS_Store
DerivedData DerivedData
*.orig *.orig
build
Playground_macOS.playground/playground.xcworkspace/xcuserdata
.swiftpm/xcode/package.xcworkspace/xcuserdata
.swiftpm/xcode/xcuserdata
Playground_iOS.playground/playground.xcworkspace/xcuserdata
LegacyDemo/LegacyDemo.xcodeproj/xcuserdata
Demo/Demo.xcodeproj/xcuserdata

15
.jazzy.yaml Normal file
View File

@@ -0,0 +1,15 @@
author: John Estropia
author_url: https://github.com/JohnEstropia
github_url: https://github.com/JohnEstropia/CoreStore
module: CoreStore
readme: README.md
include: Sources/*
output: docs
theme: fullwidth
clean: true
skip_undocumented: true
xcodebuild_arguments:
- -sdk
- iphonesimulator
- -scheme
- CoreStore iOS

View File

@@ -1 +0,0 @@
3.1

View File

@@ -2,6 +2,6 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "self:CoreStoreDemo.xcodeproj"> location = "self:">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@@ -2,9 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key> <key>IDEDidComputeMac32BitWarning</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<true/> <true/>
</dict> </dict>
</plist> </plist>

View File

@@ -1,45 +0,0 @@
language: objective-c
osx_image: xcode8.3
sudo: false
git:
submodules: false
notifications:
email: false
env:
global:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
matrix:
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
before_install:
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.20.1/Carthage.pkg"
- sudo installer -pkg "Carthage.pkg" -target /
- rm "Carthage.pkg"
before_script:
- carthage update --use-submodules
script:
- set -o pipefail
- xcodebuild -version
- xcodebuild -showsdks
- if [ $RUN_TESTS == "YES" ]; then
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
fi
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
- if [ $POD_LINT == "YES" ]; then
pod lib lint --quick;
fi

View File

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -1,20 +1,35 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "CoreStore" s.name = "CoreStore"
s.version = "4.0.0-beta" s.version = "9.3.0"
s.swift_version = "5.9"
s.license = "MIT" s.license = "MIT"
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
s.homepage = "https://github.com/JohnEstropia/CoreStore" s.homepage = "https://github.com/JohnEstropia/CoreStore"
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" } s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s } s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
s.ios.deployment_target = "8.0" s.ios.deployment_target = "16.0"
s.osx.deployment_target = "10.10" s.osx.deployment_target = "13.0"
s.watchos.deployment_target = "2.0" s.tvos.deployment_target = "16.0"
s.tvos.deployment_target = "9.0" s.watchos.deployment_target = "9.0"
s.source_files = "Sources", "Sources/**/*.{swift,h,m}" s.source_files = "Sources", "Sources/**/*.swift"
s.public_header_files = "Sources/**/*.h" s.public_header_files = "Sources/**/*.h"
s.frameworks = "Foundation", "CoreData" s.frameworks = "Foundation", "CoreData"
s.requires_arc = true s.requires_arc = true
s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG' } s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG', 'OTHER_LDFLAGS' => '-weak_framework Combine -weak_framework SwiftUI' }
s.test_spec "CoreStoreTests" do |ts|
ts.source_files = "CoreStoreTests", "CoreStoreTests/**/*.swift", "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel"
ts.public_header_files = "CoreStoreTests/**/*.h"
ts.resources = [ "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel" ]
ts.preserve_paths = "CoreStoreTests/**/*.xcdatamodeld"
ts.resource_bundles = { 'CoreStoreTests' => ["CoreStoreTests/**/*.momd"] }
ts.frameworks = "Foundation", "CoreData"
ts.requires_arc = true
ts.ios.deployment_target = "16.0"
ts.osx.deployment_target = "13.0"
ts.tvos.deployment_target = "16.0"
end
end end

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0800" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B52DD1731BE1F8CC00949AFE"
BuildableName = "CoreStore.framework"
BlueprintName = "CoreStore OSX"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables> <Testables>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
@@ -39,17 +48,6 @@
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
</Testables> </Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B52DD1731BE1F8CC00949AFE"
BuildableName = "CoreStore.framework"
BlueprintName = "CoreStore OSX"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@@ -70,8 +68,6 @@
ReferencedContainer = "container:CoreStore.xcodeproj"> ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0800" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -41,18 +41,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2F03A53A19C5C6DA005002A5"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests iOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference
BuildableIdentifier = "primary" BuildableIdentifier = "primary"
@@ -69,6 +57,18 @@
isEnabled = "YES"> isEnabled = "YES">
</AdditionalOption> </AdditionalOption>
</AdditionalOptions> </AdditionalOptions>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "2F03A53A19C5C6DA005002A5"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests iOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@@ -89,8 +89,12 @@
ReferencedContainer = "container:CoreStore.xcodeproj"> ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions> <CommandLineArguments>
</AdditionalOptions> <CommandLineArgument
argument = "-com.apple.CoreData.SQLDebug 2"
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0800" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -27,6 +27,15 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "82BA18881C4BBCBA00A0916E"
BuildableName = "CoreStore.framework"
BlueprintName = "CoreStore tvOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables> <Testables>
<TestableReference <TestableReference
skipped = "NO"> skipped = "NO">
@@ -39,17 +48,6 @@
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
</Testables> </Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "82BA18881C4BBCBA00A0916E"
BuildableName = "CoreStore.framework"
BlueprintName = "CoreStore tvOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@@ -70,8 +68,6 @@
ReferencedContainer = "container:CoreStore.xcodeproj"> ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0800" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -20,6 +20,20 @@
ReferencedContainer = "container:CoreStore.xcodeproj"> ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference> </BuildableReference>
</BuildActionEntry> </BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests watchOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries> </BuildActionEntries>
</BuildAction> </BuildAction>
<TestAction <TestAction
@@ -28,9 +42,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"> shouldUseLaunchSchemeArgsEnv = "YES">
<Testables> <Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
BuildableName = "CoreStoreTests.xctest"
BlueprintName = "CoreStoreTests watchOS"
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables> </Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Debug" buildConfiguration = "Debug"
@@ -51,8 +73,6 @@
ReferencedContainer = "container:CoreStore.xcodeproj"> ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction
buildConfiguration = "Release" buildConfiguration = "Release"

View File

@@ -2,9 +2,9 @@
<Workspace <Workspace
version = "1.0"> version = "1.0">
<FileRef <FileRef
location = "group:CoreStore.xcodeproj"> location = "group:Demo/Demo.xcodeproj">
</FileRef> </FileRef>
<FileRef <FileRef
location = "group:CoreStoreDemo/CoreStoreDemo.xcodeproj"> location = "group:CoreStore.xcodeproj">
</FileRef> </FileRef>
</Workspace> </Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@@ -1,538 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */; };
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */; };
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; };
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977E01B120F8A003D50A5 /* CoreLocation.framework */; };
B52977E41B121635003D50A5 /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977E31B121635003D50A5 /* Place.swift */; };
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */; };
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */; };
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD571AF4D26E00848AE0 /* Main.storyboard */; };
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */; };
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */; };
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */; };
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */; };
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3311B11DF3200F4F0C6 /* UserAccount.swift */; };
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */; };
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */; };
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D91B231BCA0075EE4A /* MaleAccount.swift */; };
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */; };
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */; };
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965171B2E20CC0075EE4A /* TimeZone.swift */; };
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */; };
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */; };
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */; };
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */; };
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; };
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25841B36E23C0000406B /* OrganismV1.swift */; };
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25861B36E2520000406B /* OrganismV2.swift */; };
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */; };
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259A1B3EA4890000406B /* OrganismV3.swift */; };
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverDemoViewController.swift; sourceTree = "<group>"; };
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverDemoViewController.swift; sourceTree = "<group>"; };
B503FADD1AFDC71700F90881 /* Palette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Palette.swift; sourceTree = "<group>"; };
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaletteTableViewCell.swift; sourceTree = "<group>"; };
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV2ToV3.xcmappingmodel; sourceTree = "<group>"; };
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV3ToV2.xcmappingmodel; sourceTree = "<group>"; };
B52977D81B120B80003D50A5 /* ObserversViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserversViewController.swift; sourceTree = "<group>"; };
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsDemoViewController.swift; sourceTree = "<group>"; };
B52977DE1B120F83003D50A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
B52977E01B120F8A003D50A5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
B52977E31B121635003D50A5 /* Place.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = "<group>"; };
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreStoreDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
B54AAD4D1AF4D26E00848AE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreStoreDemo.xcdatamodel; sourceTree = "<group>"; };
B54AAD581AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
B54AAD5D1AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2ToV3MigrationPolicy.swift; sourceTree = "<group>"; };
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackSetupDemoViewController.swift; sourceTree = "<group>"; };
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserAccount.swift; sourceTree = "<group>"; };
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomLoggerViewController.swift; sourceTree = "<group>"; };
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = StackSetupDemo.xcdatamodel; sourceTree = "<group>"; };
B56964D91B231BCA0075EE4A /* MaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaleAccount.swift; sourceTree = "<group>"; };
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FemaleAccount.swift; sourceTree = "<group>"; };
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingAndQueryingDemoViewController.swift; sourceTree = "<group>"; };
B56965171B2E20CC0075EE4A /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = "<group>"; };
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingResultsViewController.swift; sourceTree = "<group>"; };
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryingResultsViewController.swift; sourceTree = "<group>"; };
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemo.xcdatamodel; sourceTree = "<group>"; };
B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OrganismTableViewCell.swift; path = "CoreStoreDemo/MIgrations Demo/OrganismTableViewCell.swift"; sourceTree = SOURCE_ROOT; };
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV2.xcdatamodel; sourceTree = "<group>"; };
B5EE25841B36E23C0000406B /* OrganismV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV1.swift; sourceTree = "<group>"; };
B5EE25861B36E2520000406B /* OrganismV2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2.swift; sourceTree = "<group>"; };
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV3.xcdatamodel; sourceTree = "<group>"; };
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationsDemoViewController.swift; sourceTree = "<group>"; };
B5EE259A1B3EA4890000406B /* OrganismV3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV3.swift; sourceTree = "<group>"; };
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismProtocol.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B54AAD461AF4D26E00848AE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */,
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */,
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */ = {
isa = PBXGroup;
children = (
B52977D81B120B80003D50A5 /* ObserversViewController.swift */,
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */,
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */,
B503FADD1AFDC71700F90881 /* Palette.swift */,
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */,
);
path = "List and Object Observers Demo";
sourceTree = "<group>";
};
B52977DB1B120F2C003D50A5 /* Transactions Demo */ = {
isa = PBXGroup;
children = (
B52977E31B121635003D50A5 /* Place.swift */,
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */,
);
path = "Transactions Demo";
sourceTree = "<group>";
};
B52977E21B120F90003D50A5 /* Frameworks */ = {
isa = PBXGroup;
children = (
B52977E01B120F8A003D50A5 /* CoreLocation.framework */,
B5BDC9211C202429008147CD /* CoreStore.framework */,
B52977DE1B120F83003D50A5 /* MapKit.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
B54AAD401AF4D26E00848AE0 = {
isa = PBXGroup;
children = (
B52977E21B120F90003D50A5 /* Frameworks */,
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */,
B54AAD4A1AF4D26E00848AE0 /* Products */,
);
sourceTree = "<group>";
};
B54AAD4A1AF4D26E00848AE0 /* Products */ = {
isa = PBXGroup;
children = (
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */ = {
isa = PBXGroup;
children = (
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */,
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */,
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */,
B52977DB1B120F2C003D50A5 /* Transactions Demo */,
B56965091B2B35370075EE4A /* Fetching and Querying Demo */,
B569652F1B3591460075EE4A /* Migrations Demo */,
B56964C61B20AC200075EE4A /* Loggers Demo */,
B54AAD571AF4D26E00848AE0 /* Main.storyboard */,
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */,
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */,
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */,
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */,
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */,
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */,
);
path = CoreStoreDemo;
sourceTree = "<group>";
};
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */ = {
isa = PBXGroup;
children = (
B54AAD4D1AF4D26E00848AE0 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */ = {
isa = PBXGroup;
children = (
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */,
B56964D91B231BCA0075EE4A /* MaleAccount.swift */,
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */,
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */,
);
path = "Stack Setup Demo";
sourceTree = "<group>";
};
B56964C61B20AC200075EE4A /* Loggers Demo */ = {
isa = PBXGroup;
children = (
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */,
);
path = "Loggers Demo";
sourceTree = "<group>";
};
B56965091B2B35370075EE4A /* Fetching and Querying Demo */ = {
isa = PBXGroup;
children = (
B56965171B2E20CC0075EE4A /* TimeZone.swift */,
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */,
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */,
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */,
);
path = "Fetching and Querying Demo";
sourceTree = "<group>";
};
B569652F1B3591460075EE4A /* Migrations Demo */ = {
isa = PBXGroup;
children = (
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */,
B5EE259A1B3EA4890000406B /* OrganismV3.swift */,
B5EE25861B36E2520000406B /* OrganismV2.swift */,
B5EE25841B36E23C0000406B /* OrganismV1.swift */,
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */,
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */,
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */,
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */,
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */,
);
path = "Migrations Demo";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */;
buildPhases = (
B54AAD451AF4D26E00848AE0 /* Sources */,
B54AAD461AF4D26E00848AE0 /* Frameworks */,
B54AAD471AF4D26E00848AE0 /* Resources */,
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = CoreStoreDemo;
productName = CoreStoreDemo;
productReference = B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
B54AAD411AF4D26E00848AE0 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "John Rommel Estropia";
TargetAttributes = {
B54AAD481AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
LastSwiftMigration = 0800;
};
};
};
buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = B54AAD401AF4D26E00848AE0;
productRefGroup = B54AAD4A1AF4D26E00848AE0 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
B54AAD471AF4D26E00848AE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */,
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */,
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B54AAD451AF4D26E00848AE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */,
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */,
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */,
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */,
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */,
B52977E41B121635003D50A5 /* Place.swift in Sources */,
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */,
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */,
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */,
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */,
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */,
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */,
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */,
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */,
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */,
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */,
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */,
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */,
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */,
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */,
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */,
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */,
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
B54AAD571AF4D26E00848AE0 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
B54AAD581AF4D26E00848AE0 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
B54AAD5D1AF4D26E00848AE0 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B54AAD6B1AF4D26E00848AE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
B54AAD6C1AF4D26E00848AE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
B54AAD6E1AF4D26E00848AE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
B54AAD6F1AF4D26E00848AE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B54AAD6B1AF4D26E00848AE0 /* Debug */,
B54AAD6C1AF4D26E00848AE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B54AAD6E1AF4D26E00848AE0 /* Debug */,
B54AAD6F1AF4D26E00848AE0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */,
);
currentVersion = B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */;
path = CoreStoreDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */,
);
currentVersion = B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */;
path = StackSetupDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */,
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */,
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */,
);
currentVersion = B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */;
path = MigrationDemo.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = B54AAD411AF4D26E00848AE0 /* Project object */;
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>B6855E48-4B19-4321-B1C7-CB2706E12777</string>
<key>IDESourceControlProjectName</key>
<string>CoreStoreDemo</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>github.com:JohnEstropia/CoreStore.git</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>github.com:JohnEstropia/GCDKit.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>CoreStoreDemo/CoreStoreDemo.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>../../..</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>../../..Libraries/GCDKit</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>github.com:JohnEstropia/CoreStore.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlWCCName</key>
<string>CoreStore</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>8B2E522D57154DFA93A06982C36315ECBEA4FA97</string>
<key>IDESourceControlWCCName</key>
<string>GCDKit</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,30 +0,0 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "4B60F1BCB491FF717C56441AE7783C74F417BE48",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"8B2E522D57154DFA93A06982C36315ECBEA4FA97" : 0,
"4B60F1BCB491FF717C56441AE7783C74F417BE48" : 0
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "B6855E48-4B19-4321-B1C7-CB2706E12777",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"8B2E522D57154DFA93A06982C36315ECBEA4FA97" : "CoreStoreLibraries\/GCDKit",
"4B60F1BCB491FF717C56441AE7783C74F417BE48" : "CoreStore"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "CoreStoreDemo",
"DVTSourceControlWorkspaceBlueprintVersion" : 203,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CoreStoreDemo\/CoreStoreDemo.xcodeproj",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:JohnEstropia\/CoreStore.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "4B60F1BCB491FF717C56441AE7783C74F417BE48"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:JohnEstropia\/GCDKit.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "8B2E522D57154DFA93A06982C36315ECBEA4FA97"
}
]
}

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>7C5E31AC-5DD0-43DA-A5C6-AF73B4532D86</string>
<key>IDESourceControlProjectName</key>
<string>project</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>github.com:JohnEstropia/HardcoreData.git</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>github.com:JohnEstropia/GCDKit.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>HardcoreDataDemo/HardcoreDataDemo.xcodeproj/project.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>4B60F1BCB491FF717C56441AE7783C74F417BE48</key>
<string>../../..</string>
<key>8B2E522D57154DFA93A06982C36315ECBEA4FA97</key>
<string>../../..Libraries/GCDKit</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>github.com:JohnEstropia/HardcoreData.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>8B2E522D57154DFA93A06982C36315ECBEA4FA97</string>
<key>IDESourceControlWCCName</key>
<string>GCDKit</string>
</dict>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>4B60F1BCB491FF717C56441AE7783C74F417BE48</string>
<key>IDESourceControlWCCName</key>
<string>HardcoreData</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,28 +0,0 @@
//
// AppDelegate.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - AppDelegate
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
// MARK: UIApplicationDelegate
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
application.statusBarStyle = .lightContent
return true
}
}

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10112" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10083"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="CoreStoreIcon" translatesAutoresizingMaskIntoConstraints="NO" id="q8C-V6-gXH">
<rect key="frame" x="155" y="83" width="170" height="170"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="273" width="440" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstItem="q8C-V6-gXH" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" multiplier="0.7" id="QW6-8Y-w15"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="q8C-V6-gXH" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="fRb-1V-9iD"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="top" secondItem="q8C-V6-gXH" secondAttribute="bottom" constant="20" id="s63-MP-ush"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
<resources>
<image name="CoreStoreIcon" width="170" height="170"/>
</resources>
</document>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<<<<<<< Updated upstream
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
=======
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
>>>>>>> Stashed changes
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<<<<<<< Updated upstream
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
=======
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439.5" width="441" height="20.5"/>
>>>>>>> Stashed changes
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="133" width="441" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="10169.1" systemVersion="15D21" minimumToolsVersion="Automatic">
<entity name="Palette" representedClassName="CoreStoreDemo.Palette">
<attribute name="brightness" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
<attribute name="colorName" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
<attribute name="hue" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
<userInfo/>
</entity>
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
</entity>
<configuration name="FetchingAndQueryingDemo">
<memberEntity name="TimeZone"/>
</configuration>
<configuration name="ObservingDemo">
<memberEntity name="Palette"/>
</configuration>
<configuration name="TransactionsDemo">
<memberEntity name="Place"/>
</configuration>
<elements>
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
</elements>
</model>

View File

@@ -1,291 +0,0 @@
//
// FetchingAndQueryingDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/12.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
static let timeZonesStack: DataStack = {
let dataStack = DataStack()
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "TimeZoneDemo.sqlite",
configuration: "FetchingAndQueryingDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<TimeZone>())
for name in NSTimeZone.knownTimeZoneNames {
let rawTimeZone = NSTimeZone(name: name)!
let cachedTimeZone = transaction.create(Into<TimeZone>())
cachedTimeZone.name = rawTimeZone.name
cachedTimeZone.abbreviation = rawTimeZone.abbreviation ?? ""
cachedTimeZone.secondsFromGMT = Int32(rawTimeZone.secondsFromGMT)
cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime
cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset
}
}
)
return dataStack
}()
}
// MARK: - FetchingAndQueryingDemoViewController
class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// MARK: UIViewController
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.didAppearOnce {
return
}
self.didAppearOnce = true
let alert = UIAlertController(
title: "Fetch and Query Demo",
message: "This demo shows how to execute fetches and queries.\n\nEach menu item executes and displays a preconfigured fetch/query.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let indexPath = sender as? IndexPath {
switch segue.destination {
case let controller as FetchingResultsViewController:
let item = self.fetchingItems[indexPath.row]
controller.set(timeZones: item.fetch(), title: item.title)
case let controller as QueryingResultsViewController:
let item = self.queryingItems[indexPath.row]
controller.set(value: item.query(), title: item.title)
default:
break
}
}
}
// MARK: UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
return self.fetchingItems.count
case Section.querying.rawValue?:
return self.queryingItems.count
default:
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
cell.textLabel?.text = self.fetchingItems[indexPath.row].title
case Section.querying.rawValue?:
cell.textLabel?.text = self.queryingItems[indexPath.row].title
default:
cell.textLabel?.text = nil
}
return cell
}
// MARK: UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch self.segmentedControl?.selectedSegmentIndex {
case Section.fetching.rawValue?:
self.performSegue(withIdentifier: "FetchingResultsViewController", sender: indexPath)
case Section.querying.rawValue?:
self.performSegue(withIdentifier: "QueryingResultsViewController", sender: indexPath)
default:
break
}
}
// MARK: Private
private enum Section: Int {
case fetching
case querying
}
private let fetchingItems = [
(
title: "All Time Zones",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
}
),
(
title: "Time Zones in Asia",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Asia"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
}
),
(
title: "Time Zones in America and Europe",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America")
|| Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Europe"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
}
),
(
title: "All Time Zones Except America",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
!Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
}
),
(
title: "Time Zones with Summer Time",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("hasDaylightSavingTime", isEqualTo: true),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
}
)
]
private let queryingItems = [
(
title: "Number of Time Zones",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>(),
Select<NSNumber>(.count(#keyPath(TimeZone.name)))
)!
}
),
(
title: "Abbreviation For Tokyo's Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>(),
Select<String>(#keyPath(TimeZone.abbreviation)),
Where("%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
)!
}
),
(
title: "All Abbreviations",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(#keyPath(TimeZone.name), #keyPath(TimeZone.abbreviation)),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
}
),
(
title: "Number of Countries per Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(.count(#keyPath(TimeZone.abbreviation)), #keyPath(TimeZone.abbreviation)),
GroupBy(#keyPath(TimeZone.abbreviation)),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)), .ascending(#keyPath(TimeZone.name)))
)!
}
),
(
title: "Number of Countries with Summer Time",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(
.count(#keyPath(TimeZone.hasDaylightSavingTime), as: "numberOfCountries"),
#keyPath(TimeZone.hasDaylightSavingTime)
),
GroupBy(#keyPath(TimeZone.hasDaylightSavingTime)),
OrderBy(.descending(#keyPath(TimeZone.hasDaylightSavingTime)))
)!
}
)
]
var didAppearOnce = false
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
@IBOutlet dynamic weak var tableView: UITableView?
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
self.tableView?.reloadData()
}
}

View File

@@ -1,68 +0,0 @@
//
// FetchingResultsViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - FetchingResultsViewController
class FetchingResultsViewController: UITableViewController {
// MARK: Public
func set(timeZones: [TimeZone]?, title: String) {
self.timeZones += timeZones ?? []
self.sectionTitle = title
self.tableView?.reloadData()
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableViewAutomaticDimension
}
// MARK: UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.timeZones.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
let timeZone = self.timeZones[indexPath.row]
cell.textLabel?.text = timeZone.name
cell.detailTextLabel?.text = timeZone.abbreviation
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionTitle
}
// MARK: Private
var timeZones = [TimeZone]()
var sectionTitle: String?
}

View File

@@ -1,88 +0,0 @@
//
// QueryingResultsViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
class QueryingResultsViewController: UITableViewController {
// MARK: Public
func set(value: Any?, title: String) {
switch value {
case (let array as [Any])?:
self.values = array.map { (item: Any) -> (title: String, detail: String) in
(
title: String(describing: item),
detail: String(reflecting: type(of: item))
)
}
case let item?:
self.values = [
(
title: String(describing: item),
detail: String(reflecting: type(of: item))
)
]
default:
self.values = []
}
self.sectionTitle = title
self.tableView?.reloadData()
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableViewAutomaticDimension
}
// MARK: UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.values.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
let value = self.values[indexPath.row]
cell.textLabel?.text = value.title
cell.detailTextLabel?.text = value.detail
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionTitle
}
// MARK: Private
var values: [(title: String, detail: String)] = []
var sectionTitle: String?
}

View File

@@ -1,20 +0,0 @@
//
// TimeZone.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/15.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class TimeZone: NSManagedObject {
@NSManaged var secondsFromGMT: Int32
@NSManaged var abbreviation: String
@NSManaged var hasDaylightSavingTime: Bool
@NSManaged var daylightSavingTimeOffset: Double
@NSManaged var name: String
}

View File

@@ -1,58 +0,0 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@3x-1.png",
"scale" : "3x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "car",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "CoreStoreIcon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "first.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "second.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,315 +0,0 @@
//
// ListObserverDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
enum Filter: String {
case all = "All Colors"
case light = "Light Colors"
case dark = "Dark Colors"
func next() -> Filter {
switch self {
case .all: return .light
case .light: return .dark
case .dark: return .all
}
}
func whereClause() -> Where {
switch self {
case .all: return Where(true)
case .light: return Where("%K >= %@", #keyPath(Palette.brightness), 0.9)
case .dark: return Where("%K <= %@", #keyPath(Palette.brightness), 0.4)
}
}
}
static var filter = Filter.all {
didSet {
self.palettes.refetch(
self.filter.whereClause(),
OrderBy(.ascending(#keyPath(Palette.hue)))
)
}
}
static let palettes: ListMonitor<Palette> = {
try! CoreStore.addStorageAndWait(
SQLiteStore(
fileName: "ColorsDemo.sqlite",
configuration: "ObservingDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
return CoreStore.monitorSectionedList(
From<Palette>(),
SectionBy(#keyPath(Palette.colorName)),
OrderBy(.ascending(#keyPath(Palette.hue)))
)
}()
}
// MARK: - ListObserverDemoViewController
class ListObserverDemoViewController: UITableViewController, ListSectionObserver {
// MARK: NSObject
deinit {
Static.palettes.removeObserver(self)
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItems = [
self.editButtonItem,
UIBarButtonItem(
barButtonSystemItem: .trash,
target: self,
action: #selector(self.resetBarButtonItemTouched(_:))
)
]
let filterBarButton = UIBarButtonItem(
title: Static.filter.rawValue,
style: .plain,
target: self,
action: #selector(self.filterBarButtonItemTouched(_:))
)
navigationItem.rightBarButtonItems = [
UIBarButtonItem(
barButtonSystemItem: .add,
target: self,
action: #selector(self.addBarButtonItemTouched(_:))
),
filterBarButton
]
self.filterBarButton = filterBarButton
Static.palettes.addObserver(self)
self.setTable(enabled: !Static.palettes.isPendingRefetch)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
switch (segue.identifier, segue.destination, sender) {
case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as Palette):
destinationViewController.palette = palette
default:
break
}
}
// MARK: UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int {
return Static.palettes.numberOfSections()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Static.palettes.numberOfObjectsInSection(section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
let palette = Static.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.performSegue(
withIdentifier: "ObjectObserverDemoViewController",
sender: Static.palettes[indexPath]
)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
switch editingStyle {
case .delete:
let palette = Static.palettes[indexPath]
CoreStore.perform(
asynchronous: { (transaction) in
transaction.delete(palette)
},
completion: { _ in }
)
default:
break
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Static.palettes.sectionInfoAtIndex(section).name
}
// MARK: ListObserver
func listMonitorWillChange(_ monitor: ListMonitor<Palette>) {
self.tableView.beginUpdates()
}
func listMonitorDidChange(_ monitor: ListMonitor<Palette>) {
self.tableView.endUpdates()
}
func listMonitorWillRefetch(_ monitor: ListMonitor<Palette>) {
self.setTable(enabled: false)
}
func listMonitorDidRefetch(_ monitor: ListMonitor<Palette>) {
self.filterBarButton?.title = Static.filter.rawValue
self.tableView.reloadData()
self.setTable(enabled: true)
}
// MARK: ListObjectObserver
func listMonitor(_ monitor: ListMonitor<Palette>, didInsertObject object: Palette, toIndexPath indexPath: IndexPath) {
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteObject object: Palette, fromIndexPath indexPath: IndexPath) {
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<Palette>, didUpdateObject object: Palette, atIndexPath indexPath: IndexPath) {
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
let palette = Static.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
}
}
func listMonitor(_ monitor: ListMonitor<Palette>, didMoveObject object: Palette, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
self.tableView.insertRows(at: [toIndexPath], with: .automatic)
}
// MARK: ListSectionObserver
func listMonitor(_ monitor: ListMonitor<Palette>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) {
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
}
// MARK: Private
private var filterBarButton: UIBarButtonItem?
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
CoreStore.perform(
asynchronous: { (transaction) in
transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
}
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
Static.filter = Static.filter.next()
}
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
CoreStore.perform(
asynchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues()
},
completion: { _ in }
)
}
private func setTable(enabled: Bool) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .beginFromCurrentState,
animations: { () -> Void in
if let tableView = self.tableView {
tableView.alpha = enabled ? 1.0 : 0.5
tableView.isUserInteractionEnabled = enabled
}
},
completion: nil
)
}
}

View File

@@ -1,200 +0,0 @@
//
// ObjectObserverDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - ObjectObserverDemoViewController
class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
var palette: Palette? {
get {
return self.monitor?.object
}
set {
guard self.monitor?.object != newValue else {
return
}
if let palette = newValue {
self.monitor = CoreStore.monitorObject(palette)
}
else {
self.monitor = nil
}
}
}
// MARK: NSObject
deinit {
self.monitor?.removeObserver(self)
}
// MARK: UIViewController
required init?(coder aDecoder: NSCoder) {
if let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue)))) {
self.monitor = CoreStore.monitorObject(palette)
}
else {
_ = try? CoreStore.perform(
synchronous: { (transaction) in
let palette = transaction.create(Into(Palette.self))
palette.setInitialValues()
}
)
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
self.monitor = CoreStore.monitorObject(palette)
}
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
self.monitor?.addObserver(self)
if let palette = self.monitor?.object {
self.reloadPaletteInfo(palette, changedKeys: nil)
}
}
// MARK: ObjectObserver
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPath>) {
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
}
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didDeleteObject object: Palette) {
self.navigationItem.rightBarButtonItem?.isEnabled = false
self.colorNameLabel?.alpha = 0.3
self.colorView?.alpha = 0.3
self.hsbLabel?.text = "Deleted"
self.hsbLabel?.textColor = UIColor.red
self.hueSlider?.isEnabled = false
self.saturationSlider?.isEnabled = false
self.brightnessSlider?.isEnabled = false
}
// MARK: Private
var monitor: ObjectMonitor<Palette>?
@IBOutlet weak var colorNameLabel: UILabel?
@IBOutlet weak var colorView: UIView?
@IBOutlet weak var hsbLabel: UILabel?
@IBOutlet weak var dateLabel: UILabel?
@IBOutlet weak var hueSlider: UISlider?
@IBOutlet weak var saturationSlider: UISlider?
@IBOutlet weak var brightnessSlider: UISlider?
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
let hue = self.hueSlider?.value ?? 0
CoreStore.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.hue = Int32(hue)
}
},
completion: { _ in }
)
}
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
let saturation = self.saturationSlider?.value ?? 0
CoreStore.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.saturation = saturation
}
},
completion: { _ in }
)
}
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
let brightness = self.brightnessSlider?.value ?? 0
CoreStore.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.brightness = brightness
}
},
completion: { _ in }
)
}
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
CoreStore.perform(
asynchronous: { [weak self] (transaction) in
transaction.delete(self?.monitor?.object)
},
completion: { _ in }
)
}
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
self.colorNameLabel?.text = palette.colorName
let color = palette.color
self.colorNameLabel?.textColor = color
self.colorView?.backgroundColor = color
self.hsbLabel?.text = palette.colorText
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.hue)) == true {
self.hueSlider?.value = Float(palette.hue)
}
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.saturation)) == true {
self.saturationSlider?.value = palette.saturation
}
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.brightness)) == true {
self.brightnessSlider?.value = palette.brightness
}
}
}

View File

@@ -1,30 +0,0 @@
//
// ObserversViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
// MARK: - ObserversViewController
class ObserversViewController: UIViewController {
// MARK: UIViewController
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Observers Demo",
message: "This demo shows how to observe changes to a list of objects. The top and bottom view controllers both observe a single shared \"ListMonitor\" instance.\n\nTap on a row to see how to observe changes made to a single object using a \"ObjectMonitor\".",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}

View File

@@ -1,77 +0,0 @@
//
// Palette.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import UIKit
import CoreData
import CoreStore
// MARK: - Palette
class Palette: NSManagedObject {
@NSManaged var hue: Int32
@NSManaged var saturation: Float
@NSManaged var brightness: Float
@objc dynamic var colorName: String {
get {
let KVCKey = #keyPath(Palette.colorName)
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
return colorName
}
let colorName: String
switch self.hue % 360 {
case 0 ..< 20: colorName = "Lower Reds"
case 20 ..< 57: colorName = "Oranges and Browns"
case 57 ..< 90: colorName = "Yellow-Greens"
case 90 ..< 159: colorName = "Greens"
case 159 ..< 197: colorName = "Blue-Greens"
case 197 ..< 241: colorName = "Blues"
case 241 ..< 297: colorName = "Violets"
case 297 ..< 331: colorName = "Magentas"
default: colorName = "Upper Reds"
}
self.setPrimitiveValue(colorName, forKey: KVCKey)
return colorName
}
set {
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
}
}
var color: UIColor {
return UIColor(
hue: CGFloat(self.hue) / 360.0,
saturation: CGFloat(self.saturation),
brightness: CGFloat(self.brightness),
alpha: 1.0
)
}
var colorText: String {
return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%"
}
func setInitialValues() {
self.hue = Int32(arc4random_uniform(360))
self.saturation = 1.0
self.brightness = Float(arc4random_uniform(70) + 30) / 100.0
}
}

View File

@@ -1,15 +0,0 @@
//
// PaletteTableViewCell.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
class PaletteTableViewCell: UITableViewCell {
@IBOutlet weak var colorView: UIView?
@IBOutlet weak var label: UILabel?
}

View File

@@ -1,123 +0,0 @@
//
// CustomLoggerViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - CustomLoggerViewController
class CustomLoggerViewController: UIViewController, CoreStoreLogger {
// MARK: NSObject
deinit {
CoreStore.logger = DefaultLogger()
}
let dataStack = DataStack()
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
try! self.dataStack.addStorageAndWait(SQLiteStore(fileName: "emptyStore.sqlite"))
CoreStore.logger = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Logger Demo",
message: "This demo shows how to plug-in any logging framework to CoreStore.\n\nThe view controller implements CoreStoreLogger and appends all logs to the text view.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// MARK: CoreStoreLogger
func log(level: LogLevel, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
DispatchQueue.main.async { [weak self] in
let levelString: String
switch level {
case .trace: levelString = "Trace"
case .notice: levelString = "Notice"
case .warning: levelString = "Warning"
case .fatal: levelString = "Fatal"
}
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log:\(levelString)] \(message)\n\n")
}
}
func log(error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
DispatchQueue.main.async { [weak self] in
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Error] \(message): \(error)\n\n")
}
}
func assert(_ condition: @autoclosure () -> Bool, message: @autoclosure () -> String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
if condition() {
return
}
let messageString = message()
DispatchQueue.main.async { [weak self] in
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Assert] \(messageString)\n\n")
}
}
// MARK: Private
@IBOutlet dynamic weak var textView: UITextView?
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
switch self.segmentedControl?.selectedSegmentIndex {
case 0?:
let request = NSFetchRequest<NSFetchRequestResult>()
Where(true).applyToFetchRequest(request)
Where(false).applyToFetchRequest(request)
case 1?:
_ = try? dataStack.addStorageAndWait(
SQLiteStore(
fileName: "emptyStore.sqlite",
configuration: "invalidStore"
)
)
case 2?:
DispatchQueue.global(qos: .background).async {
_ = self.dataStack.fetchOne(From<Palette>())
}
default:
return
}
}
}

View File

@@ -1,424 +0,0 @@
//
// MigrationsDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
// MARK: - MigrationsDemoViewController
class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewDataSource, UITableViewDelegate {
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
if let segmentedControl = self.segmentedControl {
for (index, model) in self.models.enumerated() {
segmentedControl.setTitle(
model.label,
forSegmentAt: index
)
}
}
self.set(dataStack: nil, model: nil, scrollToSelection: false)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Migrations Demo",
message: "This demo shows how to run progressive migrations and how to support multiple model versions in a single project.\n\nThe persistent store contains 10000 organisms, which gain/lose properties when the migration evolves/devolves them.\n\nYou can use the \"mutate\" button to change an organism's properties then migrate to a different model to see how its value gets affected.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
let modelMetadata = withExtendedLifetime(DataStack(modelName: "MigrationDemo")) {
(dataStack: DataStack) -> ModelMetadata in
let models = self.models
let migrations = try! dataStack.requiredMigrationsForStorage(
SQLiteStore(fileName: "MigrationDemo.sqlite")
)
guard let storeVersion = migrations.first?.sourceVersion else {
return models.first!
}
for model in models {
if model.schemaHistory.currentModelVersion == storeVersion {
return model
}
}
return models.first!
}
self.selectModelVersion(modelMetadata)
}
// MARK: ListObserver
func listMonitorWillChange(_ monitor: ListMonitor<NSManagedObject>) { }
func listMonitorDidChange(_ monitor: ListMonitor<NSManagedObject>) {
if self.lastSelectedIndexPath == nil,
let numberOfObjectsInSection = self.listMonitor?.numberOfObjectsInSection(0),
numberOfObjectsInSection > 0 {
self.tableView?.reloadData()
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: false)
}
else {
self.updateDisplay(reloadData: true, scrollToSelection: true, animated: true)
}
}
// MARK: UITableViewDataSource
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listMonitor?.numberOfObjectsInSection(0) ?? 0
}
@objc dynamic func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "OrganismTableViewCell", for: indexPath) as! OrganismTableViewCell
let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? ""
cell.dnaLabel?.text = "DNA: \(dna)"
cell.mutateButtonHandler = { [weak self] _ -> Void in
guard let `self` = self,
let dataStack = self.dataStack,
let organism = self.listMonitor?[indexPath] else {
return
}
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
self.setEnabled(false)
dataStack.perform(
asynchronous: { (transaction) in
let organism = transaction.edit(organism) as! OrganismProtocol
organism.mutate()
},
completion: { [weak self] _ in
self?.setEnabled(true)
}
)
}
return cell
}
// MARK: UITableViewDelegate
@objc dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
}
// MARK: Private
private typealias ModelMetadata = (label: String, entityType: NSManagedObject.Type, schemaHistory: SchemaHistory)
private let models: [ModelMetadata] = [
(
label: "Model V1",
entityType: OrganismV1.self,
schemaHistory: SchemaHistory(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
)
),
(
label: "Model V2",
entityType: OrganismV2.self,
schemaHistory: SchemaHistory(
modelName: "MigrationDemo",
migrationChain: [
"MigrationDemo": "MigrationDemoV2",
"MigrationDemoV3": "MigrationDemoV2"
]
)
),
(
label: "Model V3",
entityType: OrganismV3.self,
schemaHistory: SchemaHistory(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
)
)
]
private var _listMonitor: ListMonitor<NSManagedObject>?
private var listMonitor: ListMonitor<NSManagedObject>? {
return self._listMonitor
}
private var _dataStack: DataStack?
private var dataStack: DataStack? {
return self._dataStack
}
private var _lastSelectedIndexPath: IndexPath?
private var lastSelectedIndexPath: IndexPath? {
return self._lastSelectedIndexPath
}
private func setSelectedIndexPath(_ indexPath: IndexPath, scrollToSelection: Bool) {
self._lastSelectedIndexPath = indexPath
self.updateDisplay(reloadData: false, scrollToSelection: scrollToSelection, animated: true)
}
@IBOutlet private dynamic weak var headerContainer: UIView?
@IBOutlet private dynamic weak var titleLabel: UILabel?
@IBOutlet private dynamic weak var organismLabel: UILabel?
@IBOutlet private dynamic weak var segmentedControl: UISegmentedControl?
@IBOutlet private dynamic weak var progressView: UIProgressView?
@IBOutlet private dynamic weak var tableView: UITableView?
@IBAction private dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
guard let index = self.segmentedControl?.selectedSegmentIndex else {
return
}
self.selectModelVersion(self.models[index])
}
private func selectModelVersion(_ model: ModelMetadata) {
if self.dataStack?.modelVersion == model.schemaHistory.currentModelVersion {
return
}
self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack
let dataStack = DataStack(schemaHistory: model.schemaHistory)
self.setEnabled(false)
let progress = dataStack.addStorage(
SQLiteStore(
fileName: "MigrationDemo.sqlite",
migrationMappingProviders: [
CustomSchemaMappingProvider(
from: "MigrationDemoV3",
to: "MigrationDemoV2",
entityMappings: [
.transformEntity(
sourceEntity: "Organism",
destinationEntity: "Organism",
transformer: { (source, createDestination) in
let destination = createDestination()
destination.enumerateAttributes { (attribute, sourceAttribute) in
if let sourceAttribute = sourceAttribute {
destination[attribute] = source[sourceAttribute]
}
}
destination["numberOfFlippers"] = source["numberOfLimbs"]
}
)
]
)
]
),
completion: { [weak self] (result) -> Void in
guard let `self` = self else {
return
}
guard case .success = result else {
self.setEnabled(true)
return
}
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
let count = dataStack.queryValue(
From(model.entityType),
Select<Int>(.count(#keyPath(OrganismV1.dna))))!
if count > 0 {
self.setEnabled(true)
}
else {
for i: Int64 in 0 ..< 20 {
dataStack.perform(
asynchronous: { (transaction) in
for j: Int64 in 0 ..< 500 {
let organism = transaction.create(Into(model.entityType)) as! OrganismProtocol
organism.dna = (i * 500) + j + 1
organism.mutate()
}
},
completion: { _ in }
)
}
dataStack.perform(
asynchronous: { _ in },
completion: { [weak self] _ in
self?.setEnabled(true)
}
)
}
}
)
if let progress = progress {
progress.setProgressHandler { [weak self] (progress) -> Void in
self?.reloadTableHeaderWithProgress(progress)
}
}
}
private func setEnabled(_ enabled: Bool) {
UIView.animate(
withDuration: 0.2,
delay: 0,
options: .beginFromCurrentState,
animations: { () -> Void in
let navigationItem = self.navigationItem
navigationItem.leftBarButtonItem?.isEnabled = enabled
navigationItem.rightBarButtonItem?.isEnabled = enabled
navigationItem.hidesBackButton = !enabled
self.segmentedControl?.isEnabled = enabled
if let tableView = self.tableView {
tableView.alpha = enabled ? 1.0 : 0.5
tableView.isUserInteractionEnabled = enabled
}
},
completion: nil
)
}
private func set(dataStack: DataStack?, model: ModelMetadata?, scrollToSelection: Bool) {
if let dataStack = dataStack, let model = model {
self.segmentedControl?.selectedSegmentIndex = self.models
.index(
where: { (_, _, schemaHistory) -> Bool in
schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
}
)!
self._dataStack = dataStack
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
listMonitor.addObserver(self)
self._listMonitor = listMonitor
if self.lastSelectedIndexPath == nil {
if listMonitor.numberOfObjectsInSection(0) > 0 {
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: true)
}
}
}
else {
self.segmentedControl?.selectedSegmentIndex = UISegmentedControlNoSegment
self._listMonitor = nil
self._dataStack = nil
}
self.updateDisplay(reloadData: true, scrollToSelection: scrollToSelection, animated: false)
}
private func reloadTableHeaderWithProgress(_ progress: Progress) {
self.progressView?.setProgress(Float(progress.fractionCompleted), animated: true)
self.titleLabel?.text = "Migrating: \(progress.localizedDescription ?? "")"
self.organismLabel?.text = "Progressive step \(progress.localizedAdditionalDescription ?? "")"
}
private func updateDisplay(reloadData: Bool, scrollToSelection: Bool, animated: Bool) {
var lines = [String]()
var organismType = ""
if let indexPath = self.lastSelectedIndexPath, let organism = self.listMonitor?[indexPath] {
for property in organism.entity.properties {
let value = organism.value(forKey: property.name) ?? NSNull()
lines.append("\(property.name): \(value)")
}
organismType = organism.entity.managedObjectClassName
}
self.titleLabel?.text = organismType
self.organismLabel?.text = lines.joined(separator: "\n")
self.progressView?.progress = 0
self.headerContainer?.setNeedsLayout()
guard let tableView = self.tableView else {
return
}
if reloadData {
tableView.reloadData()
}
tableView.layoutIfNeeded()
if let indexPath = self.lastSelectedIndexPath,
indexPath.row < tableView.numberOfRows(inSection: 0) {
tableView.selectRow(at: indexPath,
animated: scrollToSelection && animated,
scrollPosition: scrollToSelection ? .middle : .none
)
}
}
}

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="8166.2" systemVersion="14E46" minimumToolsVersion="Xcode 7.0">
<elements/>
</model>

View File

@@ -1,16 +0,0 @@
//
// OrganismProtocol.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
protocol OrganismProtocol: class {
var dna: Int64 { get set }
func mutate()
}

View File

@@ -1,22 +0,0 @@
//
// OrganismTableViewCell.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/07/12.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
class OrganismTableViewCell: UITableViewCell {
@IBOutlet weak dynamic var dnaLabel: UILabel?
@IBOutlet weak dynamic var mutateButton: UIButton?
var mutateButtonHandler: (() -> Void)?
@IBAction dynamic func mutateButtonTouchUpInside(_ sender: UIButton?) {
self.mutateButtonHandler?()
}
}

View File

@@ -1,25 +0,0 @@
//
// OrganismV1.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV1: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
}
}

View File

@@ -1,27 +0,0 @@
//
// OrganismV2.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV2: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
@NSManaged var numberOfFlippers: Int32
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
self.numberOfFlippers = Int32(arc4random_uniform(9) / 2 * 2)
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,29 +0,0 @@
//
// OrganismV2ToV3MigrationPolicy.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import CoreData
class OrganismV2ToV3MigrationPolicy: NSEntityMigrationPolicy {
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager)
for dInstance in manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]) {
dInstance.setValue(
false,
forKey: #keyPath(OrganismV3.hasVertebrae)
)
dInstance.setValue(
sInstance.value(forKey: #keyPath(OrganismV2.numberOfFlippers)),
forKey: #keyPath(OrganismV3.numberOfLimbs)
)
}
}
}

View File

@@ -1,29 +0,0 @@
//
// OrganismV3.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class OrganismV3: NSManagedObject, OrganismProtocol {
@NSManaged var dna: Int64
@NSManaged var hasHead: Bool
@NSManaged var hasTail: Bool
@NSManaged var numberOfLimbs: Int32
@NSManaged var hasVertebrae: Bool
// MARK: OrganismProtocol
func mutate() {
self.hasHead = arc4random_uniform(2) == 1
self.hasTail = arc4random_uniform(2) == 1
self.numberOfLimbs = Int32(arc4random_uniform(9) / 2 * 2)
self.hasVertebrae = arc4random_uniform(2) == 1
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11198.3" systemVersion="15F34" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV1" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="90"/>
</elements>
</model>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11198.3" systemVersion="15F34" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV2" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="numberOfFlippers" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="105"/>
</elements>
</model>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16E195" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV3" syncable="YES">
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasVertebrae" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="numberOfLimbs" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" elementID="numberOfFlippers" syncable="YES"/>
</entity>
<elements>
<element name="Organism" positionX="-36" positionY="9" width="128" height="120"/>
</elements>
</model>

View File

@@ -1,15 +0,0 @@
//
// FemaleAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class FemaleAccount: UserAccount {
}

View File

@@ -1,15 +0,0 @@
//
// MaleAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
class MaleAccount: UserAccount {
}

View File

@@ -1,196 +0,0 @@
//
// StackSetupDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
static let maleConfiguration = "MaleAccounts"
static let femaleConfiguration = "FemaleAccounts"
static let facebookStack: DataStack = {
let dataStack = DataStack(modelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_FB_Male.sqlite",
configuration: maleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_FB_Female.sqlite",
configuration: femaleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Facebook"
account1.name = "John Smith HCD"
account1.friends = 42
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
account2.accountType = "Facebook"
account2.name = "Jane Doe HCD"
account2.friends = 314
}
)
return dataStack
}()
static let twitterStack: DataStack = {
let dataStack = DataStack(modelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_TW_Male.sqlite",
configuration: maleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_TW_Female.sqlite",
configuration: femaleConfiguration,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Twitter"
account1.name = "#johnsmith_hcd"
account1.friends = 7
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
account2.accountType = "Twitter"
account2.name = "#janedoe_hcd"
account2.friends = 100
}
)
return dataStack
}()
}
// MARK: - StackSetupDemoViewController
class StackSetupDemoViewController: UITableViewController {
let accounts = [
Static.facebookStack.fetchAll(From(UserAccount.self)) ?? [],
Static.twitterStack.fetchAll(From(UserAccount.self)) ?? []
]
// MARK: UIViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tableView.reloadData()
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
self.updateDetails(account: self.accounts[indexPath.section][indexPath.row])
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Setup Demo",
message: "This demo shows how to initialize 2 DataStacks with 2 configurations each, for a total of 4 SQLite files, each with 1 instance of a \"UserAccount\" entity.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// MARK: UITableViewDataSource
override func numberOfSections(in tableView: UITableView) -> Int {
return self.accounts.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.accounts[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
let account = self.accounts[indexPath.section][indexPath.row]
cell.textLabel?.text = account.name
cell.detailTextLabel?.text = "\(account.friends) friends"
return cell
}
// MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let account = self.accounts[indexPath.section][indexPath.row]
self.updateDetails(account: account)
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
let count = self.accounts[section].count
return "Facebook Accounts (\(count) users)"
case 1:
let count = self.accounts[section].count
return "Twitter Accounts (\(count) users)"
default:
return nil
}
}
// MARK: Private
@IBOutlet private dynamic weak var accountTypeLabel: UILabel?
@IBOutlet private dynamic weak var nameLabel: UILabel?
@IBOutlet private dynamic weak var friendsLabel: UILabel?
private func updateDetails(account: UserAccount) {
self.accountTypeLabel?.text = account.accountType
self.nameLabel?.text = account.name
self.friendsLabel?.text = "\(account.friends) friends"
}
}

View File

@@ -1,20 +0,0 @@
//
// UserAccount.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
// MARK: - UserAccount
class UserAccount: NSManagedObject {
@NSManaged var accountType: String?
@NSManaged var name: String?
@NSManaged var friends: Int32
}

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="7701" systemVersion="14D136" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="FemaleAccount" representedClassName="CoreStoreDemo.FemaleAccount" parentEntity="UserAccount" syncable="YES"/>
<entity name="MaleAccount" representedClassName="CoreStoreDemo.MaleAccount" parentEntity="UserAccount" syncable="YES"/>
<entity name="UserAccount" representedClassName="CoreStoreDemo.UserAccount" isAbstract="YES" syncable="YES">
<attribute name="accountType" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="friends" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<configuration name="FemaleAccounts">
<memberEntity name="FemaleAccount"/>
<memberEntity name="UserAccount"/>
</configuration>
<configuration name="MaleAccounts">
<memberEntity name="MaleAccount"/>
<memberEntity name="UserAccount"/>
</configuration>
<elements>
<element name="UserAccount" positionX="-63" positionY="-18" width="128" height="90"/>
<element name="MaleAccount" positionX="-54" positionY="18" width="128" height="45"/>
<element name="FemaleAccount" positionX="-36" positionY="27" width="128" height="45"/>
</elements>
</model>

View File

@@ -1,50 +0,0 @@
//
// Place.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import Foundation
import CoreData
import MapKit
// MARK: - Place
class Place: NSManagedObject, MKAnnotation {
@NSManaged var latitude: Double
@NSManaged var longitude: Double
@NSManaged var title: String?
@NSManaged var subtitle: String?
func setInitialValues() {
self.latitude = Double(arc4random_uniform(180)) - 90
self.longitude = Double(arc4random_uniform(360)) - 180
self.title = "\(self.latitude), \(self.longitude)"
self.subtitle = nil
}
// MARK: MKAnnotation
var coordinate: CLLocationCoordinate2D {
get {
return CLLocationCoordinate2DMake(
self.latitude,
self.longitude
)
}
set {
self.latitude = newValue.latitude
self.longitude = newValue.longitude
self.title = "\(self.latitude), \(self.longitude)"
self.subtitle = nil
}
}
}

View File

@@ -1,218 +0,0 @@
//
// TransactionsDemoViewController.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreLocation
import MapKit
import AddressBookUI
import CoreStore
private struct Static {
static let placeController: ObjectMonitor<Place> = {
try! CoreStore.addStorageAndWait(
SQLiteStore(
fileName: "PlaceDemo.sqlite",
configuration: "TransactionsDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
var place = CoreStore.fetchOne(From<Place>())
if place == nil {
_ = try? CoreStore.perform(
synchronous: { (transaction) in
let place = transaction.create(Into<Place>())
place.setInitialValues()
}
)
place = CoreStore.fetchOne(From<Place>())
}
return CoreStore.monitorObject(place!)
}()
}
// MARK: - TransactionsDemoViewController
class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, ObjectObserver {
// MARK: NSObject
deinit {
Static.placeController.removeObserver(self)
}
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
let longPressGesture = UILongPressGestureRecognizer(
target: self,
action: #selector(self.longPressGestureRecognized(_:))
)
self.mapView?.addGestureRecognizer(longPressGesture)
Static.placeController.addObserver(self)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.refreshButtonTapped(_:))
)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alert = UIAlertController(
title: "Transactions Demo",
message: "This demo shows how to use the 3 types of transactions to save updates: synchronous, asynchronous, and unsafe.\n\nTap and hold on the map to change the pin location.",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let mapView = self.mapView, let place = Static.placeController.object {
mapView.addAnnotation(place)
mapView.setCenter(place.coordinate, animated: false)
mapView.selectAnnotation(place, animated: false)
}
}
// MARK: MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "MKAnnotationView"
var annotationView: MKPinAnnotationView! = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
annotationView.animatesDrop = true
}
else {
annotationView.annotation = annotation
}
return annotationView
}
// MARK: ObjectObserver
func objectMonitor(_ monitor: ObjectMonitor<Place>, willUpdateObject object: Place) {
// none
}
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPath>) {
if let mapView = self.mapView {
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotation(object)
mapView.setCenter(object.coordinate, animated: true)
mapView.selectAnnotation(object, animated: true)
if changedPersistentKeys.contains(#keyPath(Place.latitude)) || changedPersistentKeys.contains(#keyPath(Place.longitude)) {
self.geocode(place: object)
}
}
}
func objectMonitor(_ monitor: ObjectMonitor<Place>, didDeleteObject object: Place) {
// none
}
// MARK: Private
var geocoder: CLGeocoder?
@IBOutlet weak var mapView: MKMapView?
@IBAction dynamic func longPressGestureRecognized(_ sender: AnyObject?) {
if let mapView = self.mapView,
let gesture = sender as? UILongPressGestureRecognizer,
gesture.state == .began {
let coordinate = mapView.convert(
gesture.location(in: mapView),
toCoordinateFrom: mapView
)
CoreStore.perform(
asynchronous: { (transaction) in
let place = transaction.edit(Static.placeController.object)
place?.coordinate = coordinate
},
completion: { _ in }
)
}
}
@IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) {
_ = try? CoreStore.perform(
synchronous: { (transaction) in
let place = transaction.edit(Static.placeController.object)
place?.setInitialValues()
}
)
}
func geocode(place: Place) {
let transaction = CoreStore.beginUnsafe()
self.geocoder?.cancelGeocode()
let geocoder = CLGeocoder()
self.geocoder = geocoder
geocoder.reverseGeocodeLocation(
CLLocation(latitude: place.latitude, longitude: place.longitude),
completionHandler: { [weak self] (placemarks, error) -> Void in
if let placemark = placemarks?.first, let addressDictionary = placemark.addressDictionary {
let place = transaction.edit(Static.placeController.object)
place?.title = placemark.name
place?.subtitle = ABCreateStringWithAddressDictionary(addressDictionary, true)
transaction.commit { (_) -> Void in }
}
self?.geocoder = nil
}
)
}
}

Binary file not shown.

View File

@@ -2,7 +2,7 @@
// BaseTestCase.swift // BaseTestCase.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -28,6 +28,17 @@ import XCTest
@testable @testable
import CoreStore import CoreStore
#if !SWIFT_PACKAGE
extension Bundle {
static var module: Bundle {
return Bundle(for: BaseTestCase.self)
}
}
#endif
// MARK: - BaseTestCase // MARK: - BaseTestCase
@@ -36,12 +47,11 @@ class BaseTestCase: XCTestCase {
// MARK: Internal // MARK: Internal
@nonobjc @nonobjc
@discardableResult func prepareStack(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) throws -> Void) {
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -51,36 +61,66 @@ class BaseTestCase: XCTestCase {
SQLiteStore( SQLiteStore(
fileURL: SQLiteStore.defaultRootDirectory fileURL: SQLiteStore.defaultRootDirectory
.appendingPathComponent(UUID().uuidString) .appendingPathComponent(UUID().uuidString)
.appendingPathComponent("\(type(of: self))_\(($0 ?? "-null-")).sqlite"), .appendingPathComponent("\(Self.self)_\(($0 ?? "-null-")).sqlite"),
configuration: $0, configuration: $0,
localStorageOptions: .recreateStoreOnModelMismatch localStorageOptions: .recreateStoreOnModelMismatch
) )
) )
} }
try closure(stack)
} }
catch let error as NSError { catch let error as NSError {
XCTFail(error.coreStoreDumpString) XCTFail(error.coreStoreDumpString)
} }
return closure(stack) self.addTeardownBlock {
stack.unsafeRemoveAllPersistentStoresAndWait()
}
} }
@nonobjc @nonobjc
func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () -> T) -> T { func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () throws -> T) rethrows -> T {
CoreStore.logger = TestLogger(self.prepareLoggerExpectations(expectations)) CoreStoreDefaults.logger = TestLogger(self.prepareLoggerExpectations(expectations))
defer { defer {
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
CoreStore.logger = TestLogger([:]) CoreStoreDefaults.logger = TestLogger([:])
} }
return closure() return try closure()
} }
@nonobjc @nonobjc
func expectLogger(_ expectations: [TestLogger.Expectation: XCTestExpectation]) { func expectLogger(_ expectations: [TestLogger.Expectation: XCTestExpectation]) {
CoreStore.logger = TestLogger(expectations) CoreStoreDefaults.logger = TestLogger(expectations)
}
@nonobjc
func expectError<T>(code: CoreStoreErrorCode, closure: () throws -> T) {
CoreStoreDefaults.logger = TestLogger(self.prepareLoggerExpectations([.logError]))
defer {
self.checkExpectationsImmediately()
CoreStoreDefaults.logger = TestLogger([:])
}
do {
_ = try closure()
}
catch let error as CoreStoreError {
if error.errorCode == code.rawValue {
return
}
XCTFail("Expected error code \(code) different from actual error: \((error as NSError).coreStoreDumpString)")
}
catch {
XCTFail("Error not wrapped as \(Internals.typeName(CoreStoreError.self)): \((error as NSError).coreStoreDumpString)")
}
} }
@nonobjc @nonobjc
@@ -112,12 +152,12 @@ class BaseTestCase: XCTestCase {
super.setUp() super.setUp()
self.deleteStores() self.deleteStores()
CoreStore.logger = TestLogger([:]) CoreStoreDefaults.logger = TestLogger([:])
} }
override func tearDown() { override func tearDown() {
CoreStore.logger = DefaultLogger() CoreStoreDefaults.logger = DefaultLogger()
self.deleteStores() self.deleteStores()
super.tearDown() super.tearDown()
} }

View File

@@ -2,8 +2,25 @@
// BaseTestDataTestCase.swift // BaseTestDataTestCase.swift
// CoreStore // CoreStore
// //
// Created by John Rommel Estropia on 2016/06/11. // Copyright © 2018 John Rommel Estropia
// Copyright © 2016 John Rommel Estropia. All rights reserved. //
// 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 Foundation import Foundation
@@ -17,7 +34,7 @@ import CoreStore
class BaseTestDataTestCase: BaseTestCase { class BaseTestDataTestCase: BaseTestCase {
@nonobjc @nonobjc
let dateFormatter: DateFormatter = cs_lazy { let dateFormatter: DateFormatter = Internals.with {
let formatter = DateFormatter() let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX") formatter.locale = Locale(identifier: "en_US_POSIX")

View File

@@ -1,289 +0,0 @@
//
// BridgingTests.m
// 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 "BridgingTests.h"
#import <CoreStore/CoreStore.h>
#import <CoreStore/CoreStore-Swift.h>
#import "CoreStoreTests-Swift.h"
@import CoreData;
// MARK: - BridgingTests
@implementation BridgingTests
- (void)test_ThatFlags_HaveCorrectValues {
XCTAssertEqual(CSLocalStorageOptionsNone, 0);
XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1);
XCTAssertEqual(CSLocalStorageOptionsPreventProgressiveMigration, 2);
XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4);
}
- (void)test_ThatKeyPaths_AreCorrect {
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testNumber), @"testNumber");
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testString), @"testString");
XCTAssertEqualObjects(CSKeyPathOperator(count, TestEntity1, testString), @"@count.testString");
XCTAssertEqualObjects(CSKeyPathOperator(max, TestEntity1, testNumber), @"@max.testNumber");
}
- (void)test_ThatFromClauses_BridgeCorrectly {
{
CSFrom *from = CSFromClass([TestEntity1 class]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
XCTAssertNil(from.configurations);
}
{
CSFrom *from = CSFromClass([TestEntity1 class], [NSNull null]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null]];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromClass([TestEntity1 class], @"Config1");
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[@"Config1"];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromClass([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 = CSWhereFormat(@"%K == %@", @"key", @"value");
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = CSWhereValue(YES);
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = CSWherePredicate([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
}
- (void)test_ThatOrderByClauses_BridgeCorrectly {
{
CSOrderBy *orderBy = CSOrderByKey(CSSortAscending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]);
}
{
CSOrderBy *orderBy = CSOrderByKey(CSSortDescending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]);
}
{
CSOrderBy *orderBy = CSOrderByKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil);
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]];
XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors);
}
}
- (void)test_ThatGroupByClauses_BridgeCorrectly {
{
CSGroupBy *groupBy = CSGroupByKeyPath(@"key");
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
}
{
CSGroupBy *groupBy = CSGroupByKeyPaths(@[@"key1", @"key2"]);
NSArray *keyPaths = @[@"key1", @"key2"];
XCTAssertEqualObjects(groupBy.keyPaths, keyPaths);
}
}
- (void)test_ThatTweakClauses_BridgeCorrectly {
CSTweak *tweak = CSTweakRequest(^(NSFetchRequest * _Nonnull fetchRequest) {
fetchRequest.fetchLimit = 100;
});
NSFetchRequest *request = [NSFetchRequest new];
tweak.block(request);
XCTAssertEqual(request.fetchLimit, 100);
}
- (void)test_ThatIntoClauses_BridgeCorrectly {
{
CSInto *into = CSIntoClass([TestEntity1 class]);
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
}
{
CSInto *into = CSIntoClass([TestEntity1 class], [NSNull null]);
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
XCTAssertNil(into.configuration);
}
{
CSInto *into = CSIntoClass([TestEntity1 class], @"Config1");
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
XCTAssertEqualObjects(into.configuration, @"Config1");
}
}
- (void)test_ThatDataStacks_BridgeCorrectly {
CSDataStack *dataStack = [[CSDataStack alloc]
initWithModelName:@"Model"
bundle:[NSBundle bundleForClass:[self class]]
versionChain:nil];
XCTAssertNotNil(dataStack);
[CSCoreStore setDefaultStack:dataStack];
XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]);
}
- (void)test_ThatStorages_BridgeCorrectly {
NSError *memoryError;
CSInMemoryStore *memoryStorage = [CSCoreStore
addInMemoryStorageAndWait:[CSInMemoryStore new]
error:&memoryError];
XCTAssertNotNil(memoryStorage);
XCTAssertEqualObjects([[memoryStorage class] storeType], [CSInMemoryStore storeType]);
XCTAssertEqualObjects([[memoryStorage class] storeType], NSInMemoryStoreType);
XCTAssertNil(memoryStorage.configuration);
XCTAssertNil(memoryStorage.storeOptions);
XCTAssertNil(memoryError);
NSError *sqliteError;
CSSQLiteStore *sqliteStorage = [CSCoreStore
addSQLiteStorageAndWait:[CSSQLiteStore new]
error:&sqliteError];
XCTAssertNotNil(sqliteStorage);
XCTAssertEqualObjects([[sqliteStorage class] storeType], [CSSQLiteStore storeType]);
XCTAssertEqualObjects([[sqliteStorage class] storeType], NSSQLiteStoreType);
XCTAssertNil(sqliteStorage.configuration);
XCTAssertEqualObjects(sqliteStorage.storeOptions, @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" } });
XCTAssertNil(sqliteError);
}
- (void)test_ThatTransactions_BridgeCorrectly {
[CSCoreStore
setDefaultStack:[[CSDataStack alloc]
initWithModelName:@"Model"
bundle:[NSBundle bundleForClass:[self class]]
versionChain:nil]];
[CSCoreStore
addInMemoryStorageAndWait:[CSInMemoryStore new]
error:nil];
{
CSUnsafeDataTransaction *transaction = [CSCoreStore beginUnsafe];
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]);
NSError *error;
BOOL result = [transaction commitAndWaitWithError:&error];
XCTAssertTrue(result);
XCTAssertNil(error);
}
{
XCTestExpectation *expectation = [self expectationWithDescription:@"sync"];
NSError *error;
BOOL result = [CSCoreStore
beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) {
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]);
NSError *error;
XCTAssertTrue([transaction commitAndWaitWithError:&error]);
XCTAssertNil(error);
[expectation fulfill];
}
error:&error];
XCTAssertTrue(result);
XCTAssertNil(error);
}
{
XCTestExpectation *expectation = [self expectationWithDescription:@"async"];
[CSCoreStore beginAsynchronous:^(CSAsynchronousDataTransaction * _Nonnull transaction) {
XCTAssertNotNil(transaction);
XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]);
[transaction
commitWithSuccess:^{
[expectation fulfill];
}
failure:^(CSError *error){
XCTFail();
}];
}];
}
[self waitForExpectationsWithTimeout:10 handler:nil];
}
#if TARGET_OS_IOS || TARGET_OS_WATCHOS || TARGET_OS_TV
- (void)test_ThatDataStacks_CanCreateCustomFetchedResultsControllers {
[CSCoreStore
setDefaultStack:[[CSDataStack alloc]
initWithModelName:@"Model"
bundle:[NSBundle bundleForClass:[self class]]
versionChain:nil]];
[CSCoreStore
addInMemoryStorageAndWait:[CSInMemoryStore new]
error:nil];
NSFetchedResultsController *controller =
[[CSCoreStore defaultStack]
createFetchedResultsControllerFrom:CSFromClass([TestEntity1 class])
sectionBy:[CSSectionBy keyPath:CSKeyPath(TestEntity1, testString)]
fetchClauses:@[CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100),
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil),
CSTweakRequest(^(NSFetchRequest *fetchRequest) { fetchRequest.fetchLimit = 10; })]];
XCTAssertNotNil(controller);
XCTAssertEqualObjects(controller.fetchRequest.entity.managedObjectClassName, [[TestEntity1 class] description]);
XCTAssertEqualObjects(controller.sectionNameKeyPath, CSKeyPath(TestEntity1, testString));
XCTAssertEqualObjects(controller.fetchRequest.predicate,
CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100).predicate);
XCTAssertEqualObjects(controller.fetchRequest.sortDescriptors,
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil).sortDescriptors);
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10);
}
#endif
@end

View File

@@ -2,7 +2,7 @@
// ConvenienceTests.swift // ConvenienceTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,13 +23,15 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest
@testable @testable
import CoreStore import CoreStore
// MARK: - ConvenienceTests // MARK: - ConvenienceTests
@available(OSX 10.12, *)
class ConvenienceTests: BaseTestCase { class ConvenienceTests: BaseTestCase {
@objc @objc
@@ -40,8 +42,8 @@ class ConvenienceTests: BaseTestCase {
let controller = stack.createFetchedResultsController( let controller = stack.createFetchedResultsController(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testString)), SectionBy(#keyPath(TestEntity1.testString)),
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100), Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy(.ascending(#keyPath(TestEntity1.testString))), OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
Tweak { $0.fetchLimit = 10 } Tweak { $0.fetchLimit = 10 }
) )
XCTAssertEqual(controller.managedObjectContext, stack.mainContext) XCTAssertEqual(controller.managedObjectContext, stack.mainContext)
@@ -49,11 +51,11 @@ class ConvenienceTests: BaseTestCase {
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString)) XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
XCTAssertEqual( XCTAssertEqual(
controller.fetchRequest.sortDescriptors!, controller.fetchRequest.sortDescriptors!,
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
) )
XCTAssertEqual( XCTAssertEqual(
controller.fetchRequest.predicate, controller.fetchRequest.predicate,
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
) )
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10) XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
} }
@@ -64,13 +66,13 @@ class ConvenienceTests: BaseTestCase {
self.prepareStack { (stack) in self.prepareStack { (stack) in
_ = withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
let controller = transaction.createFetchedResultsController( let controller = transaction.createFetchedResultsController(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testString)), SectionBy(#keyPath(TestEntity1.testString)),
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100), Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy(.ascending(#keyPath(TestEntity1.testString))), OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
Tweak { $0.fetchLimit = 10 } Tweak { $0.fetchLimit = 10 }
) )
XCTAssertEqual(controller.managedObjectContext, transaction.context) XCTAssertEqual(controller.managedObjectContext, transaction.context)
@@ -78,11 +80,11 @@ class ConvenienceTests: BaseTestCase {
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString)) XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
XCTAssertEqual( XCTAssertEqual(
controller.fetchRequest.sortDescriptors!, controller.fetchRequest.sortDescriptors!,
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
) )
XCTAssertEqual( XCTAssertEqual(
controller.fetchRequest.predicate, controller.fetchRequest.predicate,
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
) )
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10) XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
} }

View File

@@ -1,5 +0,0 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "BridgingTests.h"

View File

@@ -2,7 +2,7 @@
// DynamicModelTests.swift // DynamicModelTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2017 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -28,32 +28,160 @@ import XCTest
@testable @testable
import CoreStore import CoreStore
#if os(macOS)
typealias Color = NSColor
#else
typealias Color = UIColor
#endif
class Animal: CoreStoreObject { class Animal: CoreStoreObject {
let species = Value.Required<String>("species", default: "Swift") @Field.Stored("species")
let master = Relationship.ToOne<Person>("master") var species: String = "Swift"
let color = Transformable.Optional<UIColor>("color")
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
var color: Color? = .blue
@Field.Relationship("master")
var master: Person?
} }
class Dog: Animal { class Dog: Animal {
let nickname = Value.Optional<String>("nickname") static let commonNicknames = ["Spot", "Benjie", "Max", "Milo"]
let age = Value.Required<Int>("age", default: 1)
let friends = Relationship.ToManyOrdered<Dog>("friends") @Field.Stored(
let friendedBy = Relationship.ToManyUnordered<Dog>("friendedBy", inverse: { $0.friends }) "nickname",
dynamicInitialValue: {
commonNicknames.randomElement()!
}
)
var nickname: String
@Field.Stored("age")
var age: Int = 1
@Field.Relationship("friends")
var friends: [Dog]
@Field.Relationship("friendedBy", inverse: \.$friends)
var friendedBy: Set<Dog>
}
struct CustomType {
var string = "customString"
}
enum Job: String, CaseIterable {
case unemployed
case engineer
case doctor
case lawyer
init?(data: Data) {
guard
let rawValue = String(data: data, encoding: .utf8),
let value = Self.init(rawValue: rawValue)
else {
return nil
}
self = value
}
func toData() -> Data {
return Data(self.rawValue.utf8)
}
} }
class Person: CoreStoreObject { class Person: CoreStoreObject {
let title = Value.Required<String>("title", default: "Mr.")
let name = Value.Required<String>( @Field.Stored(
"name", "title",
customGetter: { (`self`, getValue) in customSetter: { (object, field, newValue) in
field.primitiveValue = newValue
return "\(self.title.value) \(getValue())" object.$displayName.primitiveValue = nil
} }
) )
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master }) var title: String = "Mr."
@Field.Stored(
"name",
customSetter: { (object, field, newValue) in
field.primitiveValue = newValue
object.$displayName.primitiveValue = nil
}
)
var name: String = ""
@Field.Virtual(
"displayName",
customGetter: Person.getDisplayName(_:_:),
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
)
var displayName: String?
@Field.Virtual(
"customType",
customGetter: { (object, field) in
if let value = field.primitiveValue {
return value
}
let value = CustomType()
field.primitiveValue = value
return value
}
)
var customField: CustomType
@Field.Coded(
"job",
coder: (
encode: { $0.toData() },
decode: { $0.flatMap(Job.init(data:)) ?? .unemployed }
),
dynamicInitialValue: {
Job.allCases.randomElement()!
}
)
var job: Job
@Field.Relationship("spouse")
var spouse: Person?
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Animal>
@Field.Relationship("_spouseInverse", inverse: \.$spouse)
private var spouseInverse: Person?
private static func getDisplayName(_ object: ObjectProxy<Person>, _ field: ObjectProxy<Person>.FieldProxy<String?>) -> String? {
if let value = field.primitiveValue {
return value
}
let title = object.$title.value
let name = object.$name.value
let value = "\(title) \(name)"
field.primitiveValue = value
return value
}
private static func keyPathsAffectingDisplayName() -> Set<String> {
return [
String(keyPath: \Person.$title),
String(keyPath: \Person.$name)
]
}
} }
@@ -61,78 +189,227 @@ class Person: CoreStoreObject {
class DynamicModelTests: BaseTestDataTestCase { class DynamicModelTests: BaseTestDataTestCase {
func testDynamicModels_CanBeDeclaredCorrectly() { @objc
dynamic func test_ThatDynamicModels_CanBeDeclaredCorrectly() {
let dataStack = DataStack( let dataStack = DataStack(
CoreStoreSchema( CoreStoreSchema(
modelVersion: "V1", modelVersion: "V1",
entities: [ entities: [
Entity<Animal>("Animal"), Entity<Animal>("Animal"),
Entity<Dog>("Dog"), Entity<Dog>("Dog", indexes: [[\Dog.$nickname, \Dog.$age]]),
Entity<Person>("Person") Entity<Person>("Person")
], ],
versionLock: [ versionLock: [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a], "Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7], "Dog": [0xad6de93adc5565d, 0x7897e51253eba5a3, 0xd12b9ce0b13600f3, 0x5a4827cd794cd15e],
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b] "Person": [0xf3e6ba6016bbedc6, 0x50dedf64f0eba490, 0xa32088a0ee83468d, 0xb72d1d0b37bd0992]
] ]
) )
) )
self.prepareStack(dataStack, configurations: [nil]) { (stack) in self.prepareStack(dataStack, configurations: [nil]) { (stack) in
let k1 = Animal.keyPath({ $0.species }) let k1 = String(keyPath: \Animal.$species)
XCTAssertEqual(k1, "species") XCTAssertEqual(k1, "species")
let k2 = Dog.keyPath({ $0.species }) let k2 = String(keyPath: \Dog.$species)
XCTAssertEqual(k2, "species") XCTAssertEqual(k2, "species")
let k3 = Dog.keyPath({ $0.nickname }) let k3 = String(keyPath: \Dog.$nickname)
XCTAssertEqual(k3, "nickname") XCTAssertEqual(k3, "nickname")
let updateDone = self.expectation(description: "update-done") let updateDone = self.expectation(description: "update-done")
let fetchDone = self.expectation(description: "fetch-done") let fetchDone = self.expectation(description: "fetch-done")
let willSetPriorObserverDone = self.expectation(description: "willSet-observe-prior-done")
let willSetNotPriorObserverDone = self.expectation(description: "willSet-observe-notPrior-done")
let didSetObserverDone = self.expectation(description: "didSet-observe-done")
stack.perform( stack.perform(
asynchronous: { (transaction) in asynchronous: { (transaction) in
let animal = transaction.create(Into<Animal>()) let animal = transaction.create(Into<Animal>())
XCTAssertEqual(animal.species.value, "Swift") XCTAssertEqual(animal.species, "Swift")
XCTAssertTrue(type(of: animal.species.value) == String.self) XCTAssertTrue(type(of: animal.species) == String.self)
XCTAssertEqual(animal.color, Color.blue)
animal.species .= "Sparrow" animal.species = "Sparrow"
XCTAssertEqual(animal.species.value, "Sparrow") XCTAssertEqual(animal.species, "Sparrow")
animal.color .= .yellow animal.color = .yellow
XCTAssertEqual(animal.color.value, UIColor.yellow) XCTAssertEqual(animal.color, Color.yellow)
for property in Animal.metaProperties(includeSuperclasses: true) {
switch property.keyPath {
case String(keyPath: \Animal.$species):
XCTAssertTrue(property is FieldContainer<Animal>.Stored<String>)
case String(keyPath: \Animal.$master):
XCTAssertTrue(property is FieldContainer<Animal>.Relationship<Person?>)
case String(keyPath: \Animal.$color):
XCTAssertTrue(property is FieldContainer<Animal>.Coded<Color?>)
default:
XCTFail("Unknown KeyPath: \"\(property.keyPath)\"")
}
}
let dog = transaction.create(Into<Dog>()) let dog = transaction.create(Into<Dog>())
XCTAssertEqual(dog.species.value, "Swift") XCTAssertEqual(dog.species, "Swift")
XCTAssertEqual(dog.nickname.value, nil) XCTAssertEqual(dog.age, 1)
XCTAssertEqual(dog.age.value, 1) XCTAssertTrue(Dog.commonNicknames.contains(dog.nickname))
for property in Dog.metaProperties(includeSuperclasses: true) {
switch property.keyPath {
case String(keyPath: \Dog.$species):
XCTAssertTrue(property is FieldContainer<Animal>.Stored<String>)
case String(keyPath: \Dog.$master):
XCTAssertTrue(property is FieldContainer<Animal>.Relationship<Person?>)
case String(keyPath: \Dog.$color):
XCTAssertTrue(property is FieldContainer<Animal>.Coded<Color?>)
case String(keyPath: \Dog.$nickname):
XCTAssertTrue(property is FieldContainer<Dog>.Stored<String>)
case String(keyPath: \Dog.$age):
XCTAssertTrue(property is FieldContainer<Dog>.Stored<Int>)
case String(keyPath: \Dog.$friends):
XCTAssertTrue(property is FieldContainer<Dog>.Relationship<[Dog]>)
case String(keyPath: \Dog.$friendedBy):
XCTAssertTrue(property is FieldContainer<Dog>.Relationship<Set<Dog>>)
default:
XCTFail("Unknown KeyPath: \"\(property.keyPath)\"")
}
}
let didSetObserver = dog.observe(\.$species, options: [.new, .old]) { (object, change) in
XCTAssertEqual(object, dog)
XCTAssertEqual(change.kind, .setting)
XCTAssertEqual(change.newValue, "Dog")
XCTAssertEqual(change.oldValue, "Swift")
XCTAssertFalse(change.isPrior)
XCTAssertEqual(object.species, "Dog")
didSetObserverDone.fulfill()
}
let willSetObserver = dog.observe(\.$species, options: [.new, .old, .prior]) { (object, change) in
XCTAssertEqual(object, dog)
XCTAssertEqual(change.kind, .setting)
XCTAssertEqual(change.oldValue, "Swift")
if change.isPrior {
XCTAssertNil(change.newValue)
XCTAssertEqual(object.species, "Swift")
willSetPriorObserverDone.fulfill()
}
else {
XCTAssertEqual(change.newValue, "Dog")
XCTAssertEqual(object.species, "Dog")
willSetNotPriorObserverDone.fulfill()
}
}
dog.species .= "Dog" dog.species = "Dog"
XCTAssertEqual(dog.species.value, "Dog") XCTAssertEqual(dog.species, "Dog")
didSetObserver.invalidate()
willSetObserver.invalidate()
dog.nickname .= "Spot" dog.nickname = "Spot"
XCTAssertEqual(dog.nickname.value, "Spot") XCTAssertEqual(dog.nickname, "Spot")
let person = transaction.create(Into<Person>()) let person = transaction.create(Into<Person>())
XCTAssertTrue(person.pets.value.isEmpty) XCTAssertTrue(person.pets.isEmpty)
XCTAssertEqual(person.customField.string, "customString")
let initialJob = person.job
XCTAssertTrue(Job.allCases.contains(initialJob))
person.name .= "John" XCTAssertEqual(
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter person.rawObject!
.runtimeType()
.keyPathsForValuesAffectingValue(forKey: "displayName"),
["title", "name"]
)
person.title .= "Sir" person.name = "Joe"
XCTAssertEqual(person.name.value, "Sir John")
person.pets.value.insert(dog) XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
person.rawObject!.setValue("AAAA", forKey: "displayName")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
person.name = "John"
XCTAssertEqual(person.name, "John")
XCTAssertEqual(person.displayName, "Mr. John") // Custom getter
let personSnapshot1 = person.asSnapshot(in: transaction)!
XCTAssertEqual(person.name, personSnapshot1.$name)
XCTAssertEqual(person.title, personSnapshot1.$title)
XCTAssertEqual(person.displayName, personSnapshot1.$displayName)
XCTAssertEqual(person.job, personSnapshot1.$job)
person.title = "Sir"
XCTAssertEqual(person.displayName, "Sir John")
XCTAssertEqual(personSnapshot1.$name, "John")
XCTAssertEqual(personSnapshot1.$title, "Mr.")
XCTAssertEqual(personSnapshot1.$displayName, "Mr. John")
person.customField.string = "newCustomString"
XCTAssertEqual(person.customField.string, "newCustomString")
person.job = .engineer
XCTAssertEqual(person.job, .engineer)
let personSnapshot2 = person.asSnapshot(in: transaction)!
XCTAssertEqual(person.name, personSnapshot2.$name)
XCTAssertEqual(person.title, personSnapshot2.$title)
XCTAssertEqual(person.displayName, personSnapshot2.$displayName)
XCTAssertEqual(person.job, personSnapshot2.$job)
var personSnapshot3 = personSnapshot2
personSnapshot3.$name = "James"
XCTAssertEqual(personSnapshot1.$name, "John")
XCTAssertEqual(personSnapshot1.$displayName, "Mr. John")
XCTAssertEqual(personSnapshot1.$job, initialJob)
XCTAssertEqual(personSnapshot2.$name, "John")
XCTAssertEqual(personSnapshot2.$displayName, "Sir John")
XCTAssertEqual(personSnapshot2.$job, .engineer)
XCTAssertEqual(personSnapshot3.$name, "James")
XCTAssertEqual(personSnapshot3.$displayName, "Sir John")
XCTAssertEqual(personSnapshot3.$job, .engineer)
person.pets.insert(dog)
XCTAssertEqual(person.pets.count, 1) XCTAssertEqual(person.pets.count, 1)
XCTAssertEqual(person.pets.value.first, dog) XCTAssertEqual(person.pets.first, dog)
XCTAssertEqual(person.pets.value.first?.master.value, person) XCTAssertEqual(person.pets.first?.master, person)
XCTAssertEqual(dog.master.value, person) XCTAssertEqual(dog.master, person)
XCTAssertEqual(dog.master.value?.pets.value.first, dog) XCTAssertEqual(dog.master?.pets.first, dog)
}, },
success: { success: { _ in
let person = try! stack.fetchOne(From<Person>())
XCTAssertNotNil(person)
let personPublisher = person!.asPublisher(in: stack)
XCTAssertEqual(personPublisher.$name, "John")
XCTAssertEqual(personPublisher.$displayName, "Sir John")
XCTAssertEqual(personPublisher.$job, .engineer)
updateDone.fulfill() updateDone.fulfill()
}, },
failure: { _ in failure: { _ in
@@ -143,40 +420,92 @@ class DynamicModelTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) in asynchronous: { (transaction) in
let p1 = Animal.where({ $0.species == "Sparrow" }) let p1 = Where<Animal>({ $0.$species == "Sparrow" })
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow")) XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
let bird = transaction.fetchOne(From<Animal>(), p1) let bird = try transaction.fetchOne(From<Animal>(), p1)
XCTAssertNotNil(bird) XCTAssertNotNil(bird)
XCTAssertEqual(bird!.species.value, "Sparrow") XCTAssertEqual(bird!.species, "Sparrow")
XCTAssertEqual(bird!.color, Color.yellow)
let p2 = Dog.where({ $0.nickname == "Spot" }) let p2 = Where<Dog>({ $0.$nickname == "Spot" })
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot")) XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
let dog = transaction.fetchOne(From<Dog>(), p2) let dog = try transaction.fetchOne(From<Dog>().where(\.$nickname == "Spot"))
XCTAssertNotNil(dog) XCTAssertNotNil(dog)
XCTAssertEqual(dog!.nickname.value, "Spot") XCTAssertEqual(dog!.nickname, "Spot")
XCTAssertEqual(dog!.species.value, "Dog") XCTAssertEqual(dog!.species, "Dog")
let person = transaction.fetchOne(From<Person>()) let person = try transaction.fetchOne(From<Person>())
XCTAssertNotNil(person) XCTAssertNotNil(person)
XCTAssertEqual(person!.pets.value.first, dog) XCTAssertEqual(person!.name, "John")
XCTAssertEqual(person!.title, "Sir")
XCTAssertEqual(person!.displayName, "Sir John")
XCTAssertEqual(person!.customField.string, "customString")
XCTAssertEqual(person!.job, .engineer)
XCTAssertEqual(person!.pets.first, dog)
let p3 = Dog.where({ $0.age == 10 }) let p3 = Where<Dog>({ $0.$age == 10 })
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10)) XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
let totalAge = try transaction.queryValue(
From<Dog>().select(Int.self, .sum(\.$age))
)
XCTAssertEqual(totalAge, 1)
_ = try transaction.fetchAll(
From<Dog>()
.where(\Animal.$species == "Dog" && \Dog.$age == 10)
)
_ = try transaction.fetchAll(
From<Dog>()
.where(\Dog.$age == 10 && \Animal.$species == "Dog")
.orderBy(.ascending({ $0.$species }))
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.$species == "Dog" && $0.$age == 10 })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.$age == 10 && $0.$species == "Dog" })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
)
_ = try transaction.fetchAll(
From<Dog>(),
(\Dog.$age > 10 && \Dog.$age <= 15)
)
}, },
success: { success: { _ in
fetchDone.fulfill() fetchDone.fulfill()
withExtendedLifetime(stack, {})
}, },
failure: { _ in failure: { _ in
XCTFail() XCTFail()
} }
) )
self.waitAndCheckExpectations()
} }
self.waitForExpectations(timeout: 10, handler: { _ in })
self.addTeardownBlock {
dataStack.unsafeRemoveAllPersistentStoresAndWait()
}
}
@objc
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \Animal.$species), "species")
XCTAssertEqual(String(keyPath: \Dog.$species), "species")
} }
@nonobjc @nonobjc
@@ -190,7 +519,7 @@ class DynamicModelTests: BaseTestDataTestCase {
SQLiteStore( SQLiteStore(
fileURL: SQLiteStore.defaultRootDirectory fileURL: SQLiteStore.defaultRootDirectory
.appendingPathComponent(UUID().uuidString) .appendingPathComponent(UUID().uuidString)
.appendingPathComponent("\(type(of: self))_\((configuration ?? "-null-")).sqlite"), .appendingPathComponent("\(Self.self)_\((configuration ?? "-null-")).sqlite"),
configuration: configuration, configuration: configuration,
localStorageOptions: .recreateStoreOnModelMismatch localStorageOptions: .recreateStoreOnModelMismatch
) )

View File

@@ -2,7 +2,7 @@
// ErrorTests.swift // ErrorTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -42,14 +42,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [:] let userInfo: NSDictionary = [:]
let objcError = error.bridgeToObjectiveC let objcError = error as NSError
XCTAssertEqual(error, objcError.bridgeToSwift)
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue) XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(error, objcError2.bridgeToSwift)
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -67,14 +65,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [ let userInfo: NSDictionary = [
"existingPersistentStoreURL": dummyURL "existingPersistentStoreURL": dummyURL
] ]
let objcError = error.bridgeToObjectiveC let objcError = error as NSError
XCTAssertEqual(error, objcError.bridgeToSwift)
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue) XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(error, objcError2.bridgeToSwift)
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -86,8 +82,10 @@ final class ErrorTests: XCTestCase {
let dummyURL = URL(string: "file:///test1/test2.sqlite")! let dummyURL = URL(string: "file:///test1/test2.sqlite")!
let schemaHistory = SchemaHistory( let schemaHistory = SchemaHistory(
modelName: "Model", XcodeDataModelSchema.from(
bundle: Bundle(for: type(of: self)) modelName: "Model",
bundle: Bundle.module
)
) )
let version = "1.0.0" let version = "1.0.0"
@@ -100,14 +98,12 @@ final class ErrorTests: XCTestCase {
"targetModel": schemaHistory.rawModel, "targetModel": schemaHistory.rawModel,
"targetModelVersion": version "targetModelVersion": version
] ]
let objcError = error.bridgeToObjectiveC let objcError = error as NSError
XCTAssertEqual(error, objcError.bridgeToSwift)
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue) XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(error, objcError2.bridgeToSwift)
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -125,14 +121,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [ let userInfo: NSDictionary = [
"localStoreURL": dummyURL "localStoreURL": dummyURL
] ]
let objcError = error.bridgeToObjectiveC let objcError = error as NSError
XCTAssertEqual(error, objcError.bridgeToSwift)
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue) XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(error, objcError2.bridgeToSwift)
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
@@ -157,14 +151,12 @@ final class ErrorTests: XCTestCase {
let userInfo: NSDictionary = [ let userInfo: NSDictionary = [
"NSError": internalError "NSError": internalError
] ]
let objcError = error.bridgeToObjectiveC let objcError = error as NSError
XCTAssertEqual(error, objcError.bridgeToSwift)
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue) XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue)
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC let objcError2 = CoreStoreError(objcError) as NSError
XCTAssertEqual(error, objcError2.bridgeToSwift)
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue)
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
// FromTests.swift // FromTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -74,33 +75,31 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>() let from = From<TestEntity1>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"]) XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
} }
do { do {
let from = From<TestEntity1>("Config1") let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
} }
@@ -115,102 +114,98 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>() let from = From<TestEntity1>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"]) XCTAssertEqual(affectedConfigurations, ["Config1"])
} }
do { do {
let from = From<TestEntity1>("Config1") let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"]) XCTAssertEqual(affectedConfigurations, ["Config1"])
} }
do { do {
let from = From<TestEntity1>("Config2") let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>() let from = From<TestEntity2>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>("Config1") let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>("Config2") let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
} }
@@ -225,99 +220,96 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>() let from = From<TestEntity1>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(Set(affectedConfigurations), ["PF_DEFAULT_CONFIGURATION_NAME", "Config1"] as Set) XCTAssertEqual(Set(affectedConfigurations), ["PF_DEFAULT_CONFIGURATION_NAME", "Config1"] as Set)
} }
do { do {
let from = From<TestEntity1>("Config1") let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"]) XCTAssertEqual(affectedConfigurations, ["Config1"])
} }
do { do {
let from = From<TestEntity1>("Config2") let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>() let from = From<TestEntity2>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"]) XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
} }
do { do {
let from = From<TestEntity2>("Config1") let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>("Config2") let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
} }
@@ -332,96 +324,94 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>() let from = From<TestEntity1>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"]) XCTAssertEqual(affectedConfigurations, ["Config1"])
} }
do { do {
let from = From<TestEntity1>("Config1") let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"]) XCTAssertEqual(affectedConfigurations, ["Config1"])
} }
do { do {
let from = From<TestEntity1>("Config2") let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>() let from = From<TestEntity2>()
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"]) XCTAssertEqual(affectedConfigurations, ["Config2"])
} }
do { do {
let from = From<TestEntity2>("Config1") let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = self.expectLogger([.logWarning]) { self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext) try from.applyToFetchRequest(request, context: dataStack.mainContext)
} }
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty) XCTAssertTrue(affectedConfigurations.isEmpty)
} }
do { do {
let from = From<TestEntity2>("Config2") let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext) let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound) XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity) XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores) XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName)) XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName } let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"]) XCTAssertEqual(affectedConfigurations, ["Config2"])
} }
} }

View File

@@ -2,7 +2,7 @@
// GroupByTests.swift // GroupByTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -38,14 +39,14 @@ final class GroupByTests: BaseTestCase {
do { do {
let groupBy = GroupBy() let groupBy = GroupBy<NSManagedObject>()
XCTAssertEqual(groupBy, GroupBy([] as [String])) XCTAssertEqual(groupBy, GroupBy([] as [String]))
XCTAssertNotEqual(groupBy, GroupBy("key")) XCTAssertNotEqual(groupBy, GroupBy("key"))
XCTAssertTrue(groupBy.keyPaths.isEmpty) XCTAssertTrue(groupBy.keyPaths.isEmpty)
} }
do { do {
let groupBy = GroupBy("key1") let groupBy = GroupBy<NSManagedObject>("key1")
XCTAssertEqual(groupBy, GroupBy("key1")) XCTAssertEqual(groupBy, GroupBy("key1"))
XCTAssertEqual(groupBy, GroupBy(["key1"])) XCTAssertEqual(groupBy, GroupBy(["key1"]))
XCTAssertNotEqual(groupBy, GroupBy("key2")) XCTAssertNotEqual(groupBy, GroupBy("key2"))
@@ -53,7 +54,7 @@ final class GroupByTests: BaseTestCase {
} }
do { do {
let groupBy = GroupBy("key1", "key2") let groupBy = GroupBy<NSManagedObject>("key1", "key2")
XCTAssertEqual(groupBy, GroupBy("key1", "key2")) XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"])) XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1")) XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
@@ -66,10 +67,10 @@ final class GroupByTests: BaseTestCase {
self.prepareStack { (dataStack) in self.prepareStack { (dataStack) in
let groupBy = GroupBy(#keyPath(TestEntity1.testString)) let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext) try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
groupBy.applyToFetchRequest(request) groupBy.applyToFetchRequest(request)
XCTAssertNotNil(request.propertiesToGroupBy) XCTAssertNotNil(request.propertiesToGroupBy)

View File

@@ -2,7 +2,7 @@
// ImportTests.swift // ImportTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -36,33 +36,33 @@ class ImportTests: BaseTestDataTestCase {
@objc @objc
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() { dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: true))?.boolValue, true) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: true))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT)) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue) XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue) XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: true))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: true)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))) XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT))))
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true)) XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max)) XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
@@ -95,7 +95,7 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNil(object) XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
} }
) )
} }
@@ -103,7 +103,7 @@ class ImportTests: BaseTestDataTestCase {
XCTFail() XCTFail()
} }
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
} }
} }
@@ -137,9 +137,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError { catch _ as TestInsertError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = transaction.fetchOne(From<TestEntity1>()) let object = try transaction.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertNil(object?.testEntityID) XCTAssertNil(object?.testEntityID)
XCTAssertNil(object?.testBoolean) XCTAssertNil(object?.testBoolean)
@@ -182,7 +182,7 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertNil(object?.testEntityID) XCTAssertNil(object?.testEntityID)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 1)) XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
@@ -202,7 +202,7 @@ class ImportTests: BaseTestDataTestCase {
#keyPath(TestEntity1.testDate): self.dateFormatter.date(from: "2000-01-02T00:00:00Z")! #keyPath(TestEntity1.testDate): self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!
] ]
) )
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertNil(object?.testEntityID) XCTAssertNil(object?.testEntityID)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false)) XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 2)) XCTAssertEqual(object?.testNumber, NSNumber(value: 2))
@@ -254,7 +254,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray sourceArray: sourceArray
) )
XCTAssertEqual(objects.count, 1) XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = objects[0] let object = objects[0]
let dictionary = sourceArray[1] let dictionary = sourceArray[1]
@@ -316,9 +316,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError { catch _ as TestInsertError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = transaction.fetchOne(From<TestEntity1>()) let object = try transaction.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertNil(object?.testEntityID) XCTAssertNil(object?.testEntityID)
XCTAssertNil(object?.testBoolean) XCTAssertNil(object?.testBoolean)
@@ -372,7 +372,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray sourceArray: sourceArray
) )
XCTAssertEqual(objects.count, sourceArray.count) XCTAssertEqual(objects.count, sourceArray.count)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 2) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 2)
for i in 0 ..< sourceArray.count { for i in 0 ..< sourceArray.count {
@@ -424,7 +424,7 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNil(object) XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
} }
do { do {
@@ -442,20 +442,19 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNil(object) XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105)) let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects) XCTAssertEqual(existingObjects.count, 1)
XCTAssertEqual(existingObjects?.count, 1)
let existingObject = existingObjects?[0] let existingObject = existingObjects[0]
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105)) XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true)) XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5)) XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5")) XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5") XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!) XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!) XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
} }
} }
) )
@@ -504,7 +503,7 @@ class ImportTests: BaseTestDataTestCase {
) )
XCTAssertEqual(objects.count, 1) XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = objects[0] let object = objects[0]
let dictionary = sourceArray[1] let dictionary = sourceArray[1]
@@ -565,7 +564,9 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(objects.count, 2) XCTAssertEqual(objects.count, 2)
zip(objects, sourceArray) zip(objects, sourceArray)
.forEach { object, dictionary in .forEach {
let (object, dictionary) = $0
XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber) XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber)
XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber) XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber)
XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber) XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber)
@@ -616,9 +617,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError { catch _ as TestInsertError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)) let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertNil(object?.testBoolean) XCTAssertNil(object?.testBoolean)
@@ -655,21 +656,19 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestUpdateError { catch _ as TestUpdateError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105)) let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects) XCTAssertEqual(existingObjects.count, 1)
XCTAssertEqual(existingObjects?.count, 1)
let existingObject = existingObjects?[0] let existingObject = existingObjects[0]
XCTAssertNotNil(existingObject) XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105)) XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true)) XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5)) XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5")) XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5") XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!) XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
} }
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
} }
@@ -708,7 +707,7 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -733,7 +732,7 @@ class ImportTests: BaseTestDataTestCase {
] ]
) )
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertEqual(object?.testBoolean, NSNumber(value: false)) XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
@@ -743,11 +742,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!) XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!) XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)) let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(existingObjects) XCTAssertEqual(existingObjects.count, 1)
XCTAssertEqual(existingObjects?.count, 1)
let existingObject = existingObjects?[0] let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, object) XCTAssertEqual(existingObject, object)
} }
} }
@@ -797,7 +795,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray sourceArray: sourceArray
) )
XCTAssertEqual(objects.count, 1) XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = objects[0] let object = objects[0]
let dictionary = sourceArray[1] let dictionary = sourceArray[1]
@@ -862,10 +860,10 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestIDError { catch _ as TestIDError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))) XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 107))) XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
} }
transaction.unsafeContext().reset() transaction.unsafeContext().reset()
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
@@ -908,7 +906,7 @@ class ImportTests: BaseTestDataTestCase {
errorExpectation.fulfill() errorExpectation.fulfill()
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)) let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertNil(object?.testBoolean) XCTAssertNil(object?.testBoolean)
@@ -949,9 +947,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestUpdateError { catch _ as TestUpdateError {
errorExpectation.fulfill() errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105)) let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 105)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 105))
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -961,11 +959,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!) XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!) XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105)) let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects) XCTAssertEqual(existingObjects.count, 1)
XCTAssertEqual(existingObjects?.count, 1)
let existingObject = existingObjects?[0] let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, object) XCTAssertEqual(existingObject, object)
} }
transaction.context.reset() transaction.context.reset()
@@ -1016,7 +1013,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray sourceArray: sourceArray
) )
XCTAssertEqual(objects.count, sourceArray.count) XCTAssertEqual(objects.count, sourceArray.count)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
for i in 0 ..< sourceArray.count { for i in 0 ..< sourceArray.count {
let object = objects[i] let object = objects[i]
@@ -1030,11 +1027,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data) XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date) XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
} }
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105)) let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects) XCTAssertEqual(existingObjects.count, 1)
XCTAssertEqual(existingObjects?.count, 1)
let existingObject = existingObjects?[0] let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, objects[0]) XCTAssertEqual(existingObject, objects[0])
} }
) )

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>BNDL</string> <string>BNDL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0</string> <string>9.3.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>

View File

@@ -2,7 +2,7 @@
// IntoTests.swift // IntoTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -125,15 +126,4 @@ final class IntoTests: XCTestCase {
XCTAssertNotEqual(into, Into<TestEntity1>("Config2")) XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
} }
} }
@objc
dynamic func test_ThatIntoClauses_BridgeCorrectly() {
do {
let into = Into<NSManagedObject>()
let objcInto = into.bridgeToObjectiveC
XCTAssertEqual(into, objcInto.bridgeToSwift)
}
}
} }

View File

@@ -2,7 +2,7 @@
// ListObserverTests.swift // ListObserverTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -31,7 +32,6 @@ import CoreStore
// MARK: - ListObserverTests // MARK: - ListObserverTests
@available(OSX 10.12, *)
class ListObserverTests: BaseTestDataTestCase { class ListObserverTests: BaseTestDataTestCase {
@objc @objc
@@ -43,7 +43,7 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList( let monitor = stack.monitorSectionedList(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)), SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
) )
monitor.addObserver(observer) monitor.addObserver(observer)
@@ -53,8 +53,8 @@ class ListObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorWillChange:", forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -67,8 +67,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didInsertSectionExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitor:didInsertSection:toSectionIndex:", forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertSection:toSectionIndex:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -76,7 +76,7 @@ class ListObserverTests: BaseTestDataTestCase {
XCTAssertEqual( XCTAssertEqual(
((note.userInfo as NSDictionary?) ?? [:]), ((note.userInfo as NSDictionary?) ?? [:]),
[ [
"sectionInfo": monitor.sectionInfoAtIndex(0), "sectionInfo": monitor.sectionInfo(at: 0),
"sectionIndex": 0 "sectionIndex": 0
] as NSDictionary ] as NSDictionary
) )
@@ -87,8 +87,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 return events == 1
} }
) )
let didInsertObjectExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitor:didInsertObject:toIndexPath:", forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -101,9 +101,9 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"] ["indexPath", "object"]
) )
let indexPath = userInfo?["indexPath"] as? NSIndexPath let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.index(atPosition: 0), 0) XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(indexPath?.item, 0)
let object = userInfo?["object"] as? TestEntity1 let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -119,8 +119,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 2 return events == 2
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorDidChange:", forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -171,21 +171,21 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList( let monitor = stack.monitorSectionedList(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)), SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
) )
monitor.addObserver(observer) monitor.addObserver(observer)
XCTAssertTrue(monitor.hasSections()) XCTAssertTrue(monitor.hasSections())
XCTAssertEqual(monitor.numberOfSections(), 2) XCTAssertEqual(monitor.numberOfSections(), 2)
XCTAssertTrue(monitor.hasObjects()) XCTAssertTrue(monitor.hasObjects())
XCTAssertTrue(monitor.hasObjectsInSection(0)) XCTAssertTrue(monitor.hasObjects(in: 0))
XCTAssertEqual(monitor.numberOfObjectsInSection(0), 2) XCTAssertEqual(monitor.numberOfObjects(in: 0), 2)
XCTAssertEqual(monitor.numberOfObjectsInSection(1), 3) XCTAssertEqual(monitor.numberOfObjects(in: 1), 3)
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorWillChange:", forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -198,62 +198,60 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
for _ in 1 ... 2 {
_ = self.expectation(
let didUpdateObjectExpectation = self.expectation( forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
forNotification: "listMonitor:didUpdateObject:atIndexPath:", object: observer,
object: observer, handler: { (note) -> Bool in
handler: { (note) -> Bool in
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? IndexPath
let object = userInfo?["object"] as? TestEntity1
switch object?.testEntityID {
XCTAssert(events == 1 || events == 2) case NSNumber(value: 101)?:
XCTAssertEqual(indexPath?.section, 1)
XCTAssertEqual(indexPath?.item, 0)
let userInfo = note.userInfo XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertNotNil(userInfo) XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
XCTAssertEqual( XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
Set(userInfo?.keys.map({ $0 as! String }) ?? []), XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
["indexPath", "object"] XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
) XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
let indexPath = userInfo?["indexPath"] as? NSIndexPath case NSNumber(value: 102)?:
let object = userInfo?["object"] as? TestEntity1 XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.item, 0)
switch object?.testEntityID { XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
case NSNumber(value: 101)?: XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
XCTAssertEqual(indexPath?.index(atPosition: 0), 1) XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 11)) default:
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11")) XCTFail()
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
case NSNumber(value: 102)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
default:
XCTFail()
}
defer {
events += 1
}
return events == 1 || events == 2
} }
) defer {
}
let didChangeExpectation = self.expectation( events += 1
forNotification: "listMonitorDidChange:", }
return events == 1 || events == 2
}
)
_ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -270,9 +268,9 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne( if let object = try transaction.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
object.testNumber = NSNumber(value: 11) object.testNumber = NSNumber(value: 11)
object.testDecimal = NSDecimalNumber(string: "11") object.testDecimal = NSDecimalNumber(string: "11")
@@ -284,9 +282,9 @@ class ListObserverTests: BaseTestDataTestCase {
XCTFail() XCTFail()
} }
if let object = transaction.fetchOne( if let object = try transaction.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testNumber = NSNumber(value: 22) object.testNumber = NSNumber(value: 22)
object.testDecimal = NSDecimalNumber(string: "22") object.testDecimal = NSDecimalNumber(string: "22")
@@ -325,14 +323,14 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList( let monitor = stack.monitorSectionedList(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)), SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
) )
monitor.addObserver(observer) monitor.addObserver(observer)
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorWillChange:", forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -345,8 +343,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didMoveObjectExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:", forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -359,13 +357,13 @@ class ListObserverTests: BaseTestDataTestCase {
["fromIndexPath", "toIndexPath", "object"] ["fromIndexPath", "toIndexPath", "object"]
) )
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath let fromIndexPath = userInfo?["fromIndexPath"] as? IndexPath
XCTAssertEqual(fromIndexPath?.index(atPosition: 0), 0) XCTAssertEqual(fromIndexPath?.section, 0)
XCTAssertEqual(fromIndexPath?.index(atPosition: 1), 0) XCTAssertEqual(fromIndexPath?.item, 0)
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath let toIndexPath = userInfo?["toIndexPath"] as? IndexPath
XCTAssertEqual(toIndexPath?.index(atPosition: 0), 1) XCTAssertEqual(toIndexPath?.section, 1)
XCTAssertEqual(toIndexPath?.index(atPosition: 1), 1) XCTAssertEqual(toIndexPath?.item, 1)
let object = userInfo?["object"] as? TestEntity1 let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
@@ -378,8 +376,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 return events == 1
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorDidChange:", forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -396,9 +394,9 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne( if let object = try transaction.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testBoolean = NSNumber(value: true) object.testBoolean = NSNumber(value: true)
} }
@@ -433,14 +431,14 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList( let monitor = stack.monitorSectionedList(
From<TestEntity1>(), From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)), SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
) )
monitor.addObserver(observer) monitor.addObserver(observer)
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorWillChange:", forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -453,40 +451,37 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
for _ in 1 ... 2 { _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"),
let didUpdateObjectExpectation = self.expectation( object: observer,
forNotification: "listMonitor:didDeleteObject:fromIndexPath:", handler: { (note) -> Bool in
object: observer,
handler: { (note) -> Bool in XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true)
defer {
XCTAssert(events == 1 || events == 2) events += 1
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true)
defer {
events += 1
}
return events == 1 || events == 2
} }
) return events == 1 || events == 2
} }
let didDeleteSectionExpectation = self.expectation( )
forNotification: "listMonitor:didDeleteSection:fromSectionIndex:", _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -513,8 +508,8 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 3 return events == 3
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorDidChange:", forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -531,10 +526,11 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
transaction.deleteAll( let count = try transaction.deleteAll(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false) Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
) )
XCTAssertEqual(count, 2)
return transaction.hasChanges return transaction.hasChanges
}, },
success: { (hasChanges) in success: { (hasChanges) in
@@ -555,7 +551,6 @@ class ListObserverTests: BaseTestDataTestCase {
// MARK: TestListObserver // MARK: TestListObserver
@available(OSX 10.12, *)
class TestListObserver: ListSectionObserver { class TestListObserver: ListSectionObserver {
// MARK: ListObserver // MARK: ListObserver

View File

@@ -0,0 +1,303 @@
//
// ListPublisherTests.swift
// CoreStore iOS
//
// Copyright © 2018 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.
//
#if canImport(UIKit) || canImport(AppKit)
import XCTest
@testable
import CoreStore
// MARK: - ListPublisherTests
class ListPublisherTests: BaseTestDataTestCase {
@objc
dynamic func test_ThatListPublishers_CanReceiveInsertNotifications() {
self.prepareStack { (stack) in
let observer = NSObject()
let listPublisher = stack.publishList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
XCTAssertFalse(listPublisher.snapshot.hasSections())
XCTAssertFalse(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.itemIDs.isEmpty)
let didChangeExpectation = self.expectation(description: "didChange")
listPublisher.addObserver(observer) { listPublisher in
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 1)
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
let object = transaction.create(Into<TestEntity1>())
object.testBoolean = NSNumber(value: true)
object.testNumber = NSNumber(value: 1)
object.testDecimal = NSDecimalNumber(string: "1")
object.testString = "nil:TestEntity1:1"
object.testData = ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!
object.testDate = self.dateFormatter.date(from: "2000-01-01T00:00:00Z")!
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(listPublisher, {})
withExtendedLifetime(observer, {})
}
}
@objc
dynamic func test_ThatListPublishers_CanReceiveUpdateNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = NSObject()
let listPublisher = stack.publishList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 2)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 2)
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 1), 3)
let didChangeExpectation = self.expectation(description: "didChange")
listPublisher.addObserver(observer) { listPublisher in
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 2)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 2)
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 1), 3)
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
object.testNumber = NSNumber(value: 11)
object.testDecimal = NSDecimalNumber(string: "11")
object.testString = "nil:TestEntity1:11"
object.testData = ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!
object.testDate = self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!
}
else {
XCTFail()
}
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testNumber = NSNumber(value: 22)
object.testDecimal = NSDecimalNumber(string: "22")
object.testString = "nil:TestEntity1:22"
object.testData = ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!
object.testDate = self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!
}
else {
XCTFail()
}
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(listPublisher, {})
withExtendedLifetime(observer, {})
}
}
@objc
dynamic func test_ThatListPublishers_CanReceiveMoveNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = NSObject()
let listPublisher = stack.publishList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 2)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 2)
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 1), 3)
let didChangeExpectation = self.expectation(description: "didChange")
listPublisher.addObserver(observer) { listPublisher in
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 2)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 1)
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 1), 4)
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testBoolean = NSNumber(value: true)
}
else {
XCTFail()
}
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(listPublisher, {})
withExtendedLifetime(observer, {})
}
}
@objc
dynamic func test_ThatListPublishers_CanReceiveDeleteNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
let observer = NSObject()
let listPublisher = stack.publishList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 2)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 2)
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 1), 3)
let didChangeExpectation = self.expectation(description: "didChange")
listPublisher.addObserver(observer) { listPublisher in
XCTAssertTrue(listPublisher.snapshot.hasSections())
XCTAssertEqual(listPublisher.snapshot.numberOfSections, 1)
XCTAssertTrue(listPublisher.snapshot.hasItems())
XCTAssertTrue(listPublisher.snapshot.hasItems(inSectionIndex: 0))
XCTAssertEqual(listPublisher.snapshot.numberOfItems(inSectionIndex: 0), 3)
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
let count = try transaction.deleteAll(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
)
XCTAssertEqual(count, 2)
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
}
}
}
#endif

View File

@@ -2,7 +2,7 @@
// MigrationChainTests.swift // MigrationChainTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11759" systemVersion="16C67" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G91" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="TestEntity1AAA" representedClassName="CoreStoreTests.TestEntity1" syncable="YES"> <entity name="TestEntity1AAA" representedClassName=".TestEntity1" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/> <attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/> <attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> <attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
@@ -9,8 +9,10 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/> <attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/> <attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/> <attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyUnordered" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToOne" inverseEntity="TestEntity1AAA" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToManyUnordered" inverseEntity="TestEntity1AAA" syncable="YES"/>
</entity> </entity>
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES"> <entity name="TestEntity2" representedClassName=".TestEntity2" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/> <attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/> <attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/> <attribute name="testDate" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
@@ -19,6 +21,8 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/> <attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/> <attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/> <attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyOrdered" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TestEntity2" inverseName="testToOne" inverseEntity="TestEntity2" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity2" inverseName="testToManyOrdered" inverseEntity="TestEntity2" syncable="YES"/>
</entity> </entity>
<configuration name="Config1"> <configuration name="Config1">
<memberEntity name="TestEntity1AAA"/> <memberEntity name="TestEntity1AAA"/>
@@ -26,8 +30,4 @@
<configuration name="Config2"> <configuration name="Config2">
<memberEntity name="TestEntity2"/> <memberEntity name="TestEntity2"/>
</configuration> </configuration>
<elements>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="165"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="165"/>
</elements>
</model> </model>

View File

@@ -2,7 +2,7 @@
// ObjectObserverTests.swift // ObjectObserverTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -31,7 +31,6 @@ import CoreStore
// MARK: - ObjectObserverTests // MARK: - ObjectObserverTests
@available(OSX 10.12, *)
class ObjectObserverTests: BaseTestDataTestCase { class ObjectObserverTests: BaseTestDataTestCase {
@objc @objc
@@ -41,9 +40,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack) self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne( guard let object = try stack.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail() XCTFail()
return return
@@ -57,8 +56,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willUpdateExpectation = self.expectation( _ = self.expectation(
forNotification: "objectMonitor:willUpdateObject:", forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -74,8 +73,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didUpdateExpectation = self.expectation( _ = self.expectation(
forNotification: "objectMonitor:didUpdateObject:changedPersistentKeys:", forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -138,9 +137,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack) self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne( guard let object = try stack.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail() XCTFail()
return return
@@ -154,8 +153,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let didDeleteExpectation = self.expectation( _ = self.expectation(
forNotification: "objectMonitor:didDeleteObject:", forNotification: NSNotification.Name(rawValue: "objectMonitor:didDeleteObject:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -203,7 +202,6 @@ class ObjectObserverTests: BaseTestDataTestCase {
// MARK: TestObjectObserver // MARK: TestObjectObserver
@available(OSX 10.12, *)
class TestObjectObserver: ObjectObserver { class TestObjectObserver: ObjectObserver {
typealias ObjectEntityType = TestEntity1 typealias ObjectEntityType = TestEntity1
@@ -219,7 +217,7 @@ class TestObjectObserver: ObjectObserver {
) )
} }
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<KeyPath>) { func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<String>) {
NotificationCenter.default.post( NotificationCenter.default.post(
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"), name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),

View File

@@ -0,0 +1,154 @@
//
// ObjectPublisherTests.swift
// CoreStore
//
// Copyright © 2018 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: - ObjectPublisherTests
class ObjectPublisherTests: BaseTestDataTestCase {
@objc
dynamic func test_ThatObjectPublishers_CanReceiveUpdateNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail()
return
}
let observer = NSObject()
let objectPublisher = stack.publishObject(object)
XCTAssertEqual(objectPublisher.object, object)
XCTAssertNotNil(objectPublisher.snapshot)
let didChangeExpectation = self.expectation(description: "didChange")
objectPublisher.addObserver(observer) { objectPublisher in
XCTAssertEqual(objectPublisher.object?.testNumber, NSNumber(value: 10))
XCTAssertEqual(objectPublisher.object?.testString, "nil:TestEntity1:10")
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
guard let object = transaction.edit(object) else {
XCTFail()
try transaction.cancel()
}
object.testNumber = NSNumber(value: 10)
object.testString = "nil:TestEntity1:10"
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(objectPublisher, {})
withExtendedLifetime(observer, {})
}
}
@objc
dynamic func test_ThatObjectPublishers_CanReceiveDeleteNotifications() {
self.prepareStack { (stack) in
self.prepareTestDataForStack(stack)
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail()
return
}
let observer = NSObject()
let objectPublisher = stack.publishObject(object)
XCTAssertEqual(objectPublisher.object, object)
XCTAssertNotNil(objectPublisher.snapshot)
let didChangeExpectation = self.expectation(description: "didChange")
objectPublisher.addObserver(observer) { objectPublisher in
XCTAssertNil(objectPublisher.object)
XCTAssertNil(objectPublisher.snapshot)
didChangeExpectation.fulfill()
}
let saveExpectation = self.expectation(description: "save")
stack.perform(
asynchronous: { (transaction) -> Bool in
guard let object = transaction.edit(object) else {
XCTFail()
try transaction.cancel()
}
transaction.delete(object)
return transaction.hasChanges
},
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
saveExpectation.fulfill()
},
failure: { _ in
XCTFail()
}
)
self.waitAndCheckExpectations()
withExtendedLifetime(objectPublisher, {})
withExtendedLifetime(observer, {})
}
}
}

View File

@@ -2,7 +2,7 @@
// OrderByTests.swift // OrderByTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -38,21 +39,21 @@ final class OrderByTests: XCTestCase {
do { do {
let orderBy = OrderBy() let orderBy = OrderBy<NSManagedObject>()
XCTAssertEqual(orderBy, OrderBy([NSSortDescriptor]())) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([NSSortDescriptor]()))
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key", ascending: false))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key", ascending: false)))
XCTAssertTrue(orderBy.sortDescriptors.isEmpty) XCTAssertTrue(orderBy.sortDescriptors.isEmpty)
} }
do { do {
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true) let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
let orderBy = OrderBy(sortDescriptor) let orderBy = OrderBy<NSManagedObject>(sortDescriptor)
XCTAssertEqual(orderBy, OrderBy(sortDescriptor)) XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"))) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key1", ascending: false))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key1", ascending: false)))
XCTAssertEqual(orderBy, OrderBy([sortDescriptor])) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor]) XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
} }
do { do {
@@ -61,76 +62,76 @@ final class OrderByTests: XCTestCase {
NSSortDescriptor(key: "key1", ascending: true), NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
let orderBy = OrderBy(sortDescriptors) let orderBy = OrderBy<NSManagedObject>(sortDescriptors)
XCTAssertEqual(orderBy, OrderBy(sortDescriptors)) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2"))) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual( XCTAssertNotEqual(
orderBy, orderBy,
OrderBy( OrderBy<NSManagedObject>(
[ [
NSSortDescriptor(key: "key1", ascending: false), NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
) )
) )
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors) XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
} }
do { do {
let orderBy = OrderBy(.ascending("key1")) let orderBy = OrderBy<NSManagedObject>(.ascending("key1"))
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true) let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
XCTAssertEqual(orderBy, OrderBy(sortDescriptor)) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptor))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"))) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
XCTAssertEqual(orderBy, OrderBy([sortDescriptor])) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor]) XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
} }
do { do {
let orderBy = OrderBy(.ascending("key1"), .descending("key2")) let orderBy = OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"))
let sortDescriptors = [ let sortDescriptors = [
NSSortDescriptor(key: "key1", ascending: true), NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
XCTAssertEqual(orderBy, OrderBy(sortDescriptors)) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2"))) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual( XCTAssertNotEqual(
orderBy, orderBy,
OrderBy( OrderBy<NSManagedObject>(
[ [
NSSortDescriptor(key: "key1", ascending: false), NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
) )
) )
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors) XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
} }
do { do {
let sortKeys: [SortKey] = [.ascending("key1"), .descending("key2")] let sortKeys: [OrderBy<NSManagedObject>.SortKey] = [.ascending("key1"), .descending("key2")]
let orderBy = OrderBy(sortKeys) let orderBy = OrderBy<NSManagedObject>(sortKeys)
let sortDescriptors = [ let sortDescriptors = [
NSSortDescriptor(key: "key1", ascending: true), NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
XCTAssertEqual(orderBy, OrderBy(sortDescriptors)) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2"))) XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual( XCTAssertNotEqual(
orderBy, orderBy,
OrderBy( OrderBy<NSManagedObject>(
[ [
NSSortDescriptor(key: "key1", ascending: false), NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false) NSSortDescriptor(key: "key2", ascending: false)
] ]
) )
) )
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3"))) XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors) XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
} }
} }
@@ -138,15 +139,15 @@ final class OrderByTests: XCTestCase {
@objc @objc
dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() { dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() {
let orderBy1 = OrderBy(.ascending("key1")) let orderBy1 = OrderBy<NSManagedObject>(.ascending("key1"))
let orderBy2 = OrderBy(.descending("key2")) let orderBy2 = OrderBy<NSManagedObject>(.descending("key2"))
let orderBy3 = OrderBy(.ascending("key3")) let orderBy3 = OrderBy<NSManagedObject>(.ascending("key3"))
do { do {
let plusOrderBy = orderBy1 + orderBy2 + orderBy3 let plusOrderBy = orderBy1 + orderBy2 + orderBy3
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2"), .ascending("key3"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2"), .ascending("key3")))
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2) XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3) XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1) XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
@@ -158,14 +159,14 @@ final class OrderByTests: XCTestCase {
var plusOrderBy = orderBy1 var plusOrderBy = orderBy1
plusOrderBy += orderBy2 plusOrderBy += orderBy2
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2")))
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1) XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1)
XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors) XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors)
plusOrderBy += orderBy3 plusOrderBy += orderBy3
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")) + OrderBy(.ascending("key3"))) XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")) + OrderBy<NSManagedObject>(.ascending("key3")))
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2) XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3) XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1) XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
@@ -178,8 +179,8 @@ final class OrderByTests: XCTestCase {
@objc @objc
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() { dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
let orderBy = OrderBy(.ascending("key")) let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
orderBy.applyToFetchRequest(request) orderBy.applyToFetchRequest(request)
XCTAssertNotNil(request.sortDescriptors) XCTAssertNotNil(request.sortDescriptors)
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors) XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
// SectionByTests.swift // SectionByTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -31,7 +32,6 @@ import CoreStore
//MARK: - SectionByTests //MARK: - SectionByTests
@available(OSX 10.12, *)
final class SectionByTests: XCTestCase { final class SectionByTests: XCTestCase {
@objc @objc
@@ -39,13 +39,16 @@ final class SectionByTests: XCTestCase {
do { do {
let sectionBy = SectionBy("key") let sectionBy = SectionBy<NSManagedObject>("key")
XCTAssertEqual(sectionBy.sectionKeyPath, "key") XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key") XCTAssertNil(sectionBy.sectionIndexTransformer("key"))
} }
do { do {
let sectionBy = SectionBy("key") { $0.flatMap { "\($0):suffix" } } let sectionBy = SectionBy<NSManagedObject>(
"key",
sectionIndexTransformer: { $0.flatMap { "\($0):suffix" } }
)
XCTAssertEqual(sectionBy.sectionKeyPath, "key") XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix") XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
XCTAssertNil(sectionBy.sectionIndexTransformer(nil)) XCTAssertNil(sectionBy.sectionIndexTransformer(nil))

View File

@@ -2,7 +2,7 @@
// SelectTests.swift // SelectTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -38,7 +39,7 @@ final class SelectTests: XCTestCase {
do { do {
let term: SelectTerm = "attribute" let term: SelectTerm<NSManagedObject> = "attribute"
XCTAssertEqual(term, SelectTerm.attribute("attribute")) XCTAssertEqual(term, SelectTerm.attribute("attribute"))
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2")) XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute")) XCTAssertNotEqual(term, SelectTerm.average("attribute"))
@@ -58,7 +59,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.attribute("attribute") let term = SelectTerm<NSManagedObject>.attribute("attribute")
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2")) XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute")) XCTAssertNotEqual(term, SelectTerm.average("attribute"))
XCTAssertNotEqual(term, SelectTerm.count("attribute")) XCTAssertNotEqual(term, SelectTerm.count("attribute"))
@@ -82,7 +83,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.average("attribute") let term = SelectTerm<NSManagedObject>.average("attribute")
XCTAssertEqual(term, SelectTerm.average("attribute")) XCTAssertEqual(term, SelectTerm.average("attribute"))
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias")) XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.average("attribute2")) XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
@@ -106,7 +107,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.average("attribute", as: "alias") let term = SelectTerm<NSManagedObject>.average("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias")) XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2")) XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute2")) XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
@@ -135,7 +136,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.count("attribute") let term = SelectTerm<NSManagedObject>.count("attribute")
XCTAssertEqual(term, SelectTerm.count("attribute")) XCTAssertEqual(term, SelectTerm.count("attribute"))
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias")) XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.count("attribute2")) XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
@@ -159,7 +160,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.count("attribute", as: "alias") let term = SelectTerm<NSManagedObject>.count("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias")) XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2")) XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.count("attribute2")) XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
@@ -188,7 +189,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.maximum("attribute") let term = SelectTerm<NSManagedObject>.maximum("attribute")
XCTAssertEqual(term, SelectTerm.maximum("attribute")) XCTAssertEqual(term, SelectTerm.maximum("attribute"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias")) XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2")) XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
@@ -212,7 +213,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.maximum("attribute", as: "alias") let term = SelectTerm<NSManagedObject>.maximum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias")) XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2")) XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2")) XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
@@ -241,7 +242,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.minimum("attribute") let term = SelectTerm<NSManagedObject>.minimum("attribute")
XCTAssertEqual(term, SelectTerm.minimum("attribute")) XCTAssertEqual(term, SelectTerm.minimum("attribute"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias")) XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2")) XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
@@ -265,7 +266,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.minimum("attribute", as: "alias") let term = SelectTerm<NSManagedObject>.minimum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias")) XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2")) XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2")) XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
@@ -294,7 +295,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.sum("attribute") let term = SelectTerm<NSManagedObject>.sum("attribute")
XCTAssertEqual(term, SelectTerm.sum("attribute")) XCTAssertEqual(term, SelectTerm.sum("attribute"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias")) XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute2")) XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
@@ -318,7 +319,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.sum("attribute", as: "alias") let term = SelectTerm<NSManagedObject>.sum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias")) XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2")) XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute2")) XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
@@ -347,7 +348,7 @@ final class SelectTests: XCTestCase {
do { do {
let term = SelectTerm.objectID() let term = SelectTerm<NSManagedObject>.objectID()
XCTAssertEqual(term, SelectTerm.objectID()) XCTAssertEqual(term, SelectTerm.objectID())
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias")) XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias"))
XCTAssertNotEqual(term, SelectTerm.attribute("attribute")) XCTAssertNotEqual(term, SelectTerm.attribute("attribute"))
@@ -368,7 +369,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let term = SelectTerm.objectID(as: "alias") let term = SelectTerm<NSManagedObject>.objectID(as: "alias")
XCTAssertEqual(term, SelectTerm.objectID(as: "alias")) XCTAssertEqual(term, SelectTerm.objectID(as: "alias"))
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2")) XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.objectID()) XCTAssertNotEqual(term, SelectTerm.objectID())
@@ -393,12 +394,12 @@ final class SelectTests: XCTestCase {
@objc @objc
dynamic func test_ThatSelectClauses_ConfigureCorrectly() { dynamic func test_ThatSelectClauses_ConfigureCorrectly() {
let term1 = SelectTerm.attribute("attribute1") let term1 = SelectTerm<NSManagedObject>.attribute("attribute1")
let term2 = SelectTerm.attribute("attribute2") let term2 = SelectTerm<NSManagedObject>.attribute("attribute2")
let term3 = SelectTerm.attribute("attribute3") let term3 = SelectTerm<NSManagedObject>.attribute("attribute3")
do { do {
let select = Select<Int>(term1, term2, term3) let select = Select<NSManagedObject, Int>(term1, term2, term3)
XCTAssertEqual(select.selectTerms, [term1, term2, term3]) XCTAssertEqual(select.selectTerms, [term1, term2, term3])
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2]) XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3]) XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
@@ -408,7 +409,7 @@ final class SelectTests: XCTestCase {
} }
do { do {
let select = Select<Int>([term1, term2, term3]) let select = Select<NSManagedObject, Int>([term1, term2, term3])
XCTAssertEqual(select.selectTerms, [term1, term2, term3]) XCTAssertEqual(select.selectTerms, [term1, term2, term3])
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2]) XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3]) XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])

View File

@@ -2,7 +2,7 @@
// SetupTests.swift // SetupTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,9 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest
@testable @testable
import CoreStore import CoreStore
@@ -37,9 +40,10 @@ class SetupTests: BaseTestDataTestCase {
do { do {
let schemaHistory = SchemaHistory( let schemaHistory = SchemaHistory(
modelName: "Model", XcodeDataModelSchema.from(
bundle: Bundle(for: type(of: self)), modelName: "Model",
migrationChain: nil bundle: Bundle.module
)
) )
let stack = DataStack(schemaHistory: schemaHistory) let stack = DataStack(schemaHistory: schemaHistory)
XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel) XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel)
@@ -55,9 +59,6 @@ class SetupTests: BaseTestDataTestCase {
XCTAssertTrue(stack.schemaHistory.migrationChain.isEmpty) XCTAssertTrue(stack.schemaHistory.migrationChain.isEmpty)
XCTAssertTrue(stack.schemaHistory.migrationChain.rootVersions.isEmpty) XCTAssertTrue(stack.schemaHistory.migrationChain.rootVersions.isEmpty)
XCTAssertTrue(stack.schemaHistory.migrationChain.leafVersions.isEmpty) XCTAssertTrue(stack.schemaHistory.migrationChain.leafVersions.isEmpty)
CoreStore.defaultStack = stack
XCTAssertEqual(CoreStore.defaultStack, stack)
} }
do { do {
@@ -66,16 +67,13 @@ class SetupTests: BaseTestDataTestCase {
let stack = self.expectLogger([.logWarning]) { let stack = self.expectLogger([.logWarning]) {
DataStack( DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)), bundle: Bundle.module,
migrationChain: migrationChain migrationChain: migrationChain
) )
} }
XCTAssertEqual(stack.modelVersion, "Model") XCTAssertEqual(stack.modelVersion, "Model")
XCTAssertEqual(stack.schemaHistory.migrationChain, migrationChain) XCTAssertEqual(stack.schemaHistory.migrationChain, migrationChain)
CoreStore.defaultStack = stack
XCTAssertEqual(CoreStore.defaultStack, stack)
} }
} }
@@ -83,8 +81,8 @@ class SetupTests: BaseTestDataTestCase {
dynamic func test_ThatInMemoryStores_SetupCorrectly() { dynamic func test_ThatInMemoryStores_SetupCorrectly() {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -138,8 +136,8 @@ class SetupTests: BaseTestDataTestCase {
dynamic func test_ThatSQLiteStores_SetupCorrectly() { dynamic func test_ThatSQLiteStores_SetupCorrectly() {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -206,8 +204,8 @@ class SetupTests: BaseTestDataTestCase {
do { do {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
try! stack.addStorageAndWait(sqliteStore) try! stack.addStorageAndWait(sqliteStore)
self.prepareTestDataForStack(stack) self.prepareTestDataForStack(stack)
@@ -225,10 +223,10 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore() let metadata = try createStore()
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
try sqliteStore.eraseStorageAndWait( try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata, metadata: metadata,
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel() soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
) )
@@ -243,7 +241,7 @@ class SetupTests: BaseTestDataTestCase {
do { do {
let metadata = try createStore() let metadata = try createStore()
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil) try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path)) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal"))) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm"))) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
@@ -258,8 +256,8 @@ class SetupTests: BaseTestDataTestCase {
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() { dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -326,10 +324,17 @@ class SetupTests: BaseTestDataTestCase {
do { do {
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
)
try! stack.addStorageAndWait(
SQLiteStore.legacy(
fileName: sqliteStore.fileURL.lastPathComponent,
configuration: sqliteStore.configuration,
migrationMappingProviders: sqliteStore.migrationMappingProviders,
localStorageOptions: .recreateStoreOnModelMismatch
)
) )
try! stack.addStorageAndWait(sqliteStore)
self.prepareTestDataForStack(stack) self.prepareTestDataForStack(stack)
} }
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path)) XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
@@ -345,10 +350,10 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore() let metadata = try createStore()
let stack = DataStack( let stack = DataStack(
modelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
try sqliteStore.eraseStorageAndWait( try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata, metadata: metadata,
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel() soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
) )
@@ -363,7 +368,7 @@ class SetupTests: BaseTestDataTestCase {
do { do {
let metadata = try createStore() let metadata = try createStore()
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil) try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path)) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal"))) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm"))) XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))

View File

@@ -2,7 +2,7 @@
// StorageInterfaceTests.swift // StorageInterfaceTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -83,7 +84,11 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore() let store = SQLiteStore()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType) XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration) XCTAssertNil(store.configuration)
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary) XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL) XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty) XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -93,12 +98,12 @@ final class StorageInterfaceTests: XCTestCase {
@objc @objc
dynamic func test_ThatFileURLSQLiteStores_ConfigureCorrectly() { dynamic func test_ThatFileURLSQLiteStores_ConfigureCorrectly() {
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) let fileURL = FileManager.default.temporaryDirectory
.appendingPathComponent(NSUUID().uuidString, isDirectory: false)! .appendingPathComponent(UUID().uuidString, isDirectory: false)
.appendingPathExtension("db") .appendingPathExtension("db")
let mappingProvider = XcodeSchemaMappingProvider( let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2", from: "V1", to: "V2",
mappingModelBundle: Bundle(for: type(of: self)) mappingModelBundle: Bundle.module
) )
let store = SQLiteStore( let store = SQLiteStore(
@@ -109,7 +114,11 @@ final class StorageInterfaceTests: XCTestCase {
) )
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType) XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1") XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary) XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, fileURL) XCTAssertEqual(store.fileURL, fileURL)
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider]) XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
@@ -122,7 +131,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db" let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider( let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2", from: "V1", to: "V2",
mappingModelBundle: Bundle(for: type(of: self)) mappingModelBundle: Bundle.module
) )
let store = SQLiteStore( let store = SQLiteStore(
fileName: fileName, fileName: fileName,
@@ -132,7 +141,11 @@ final class StorageInterfaceTests: XCTestCase {
) )
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType) XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1") XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary) XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory) XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName) XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
@@ -167,7 +180,11 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore.legacy() let store = SQLiteStore.legacy()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType) XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration) XCTAssertNil(store.configuration)
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary) XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL, SQLiteStore.legacyDefaultFileURL) XCTAssertEqual(store.fileURL, SQLiteStore.legacyDefaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty) XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -180,7 +197,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db" let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider( let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2", from: "V1", to: "V2",
mappingModelBundle: Bundle(for: type(of: self)) mappingModelBundle: Bundle.module
) )
let store = SQLiteStore.legacy( let store = SQLiteStore.legacy(
fileName: fileName, fileName: fileName,
@@ -190,7 +207,11 @@ final class StorageInterfaceTests: XCTestCase {
) )
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType) XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1") XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary) XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.legacyDefaultRootDirectory) XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.legacyDefaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName) XCTAssertEqual(store.fileURL.lastPathComponent, fileName)

View File

@@ -2,7 +2,7 @@
// TestEntity1.swift // TestEntity1.swift
// CoreStore // CoreStore
// //
// Copyright © 2014 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -36,4 +36,6 @@ class TestEntity1: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber? @NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data? @NSManaged var testData: Data?
@NSManaged var testNil: String? @NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity1?
@NSManaged var testToManyUnordered: NSSet?
} }

View File

@@ -2,7 +2,7 @@
// TestEntity1.swift // TestEntity1.swift
// CoreStore // CoreStore
// //
// Copyright © 2014 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -36,4 +36,6 @@ class TestEntity2: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber? @NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data? @NSManaged var testData: Data?
@NSManaged var testNil: String? @NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity2?
@NSManaged var testToManyOrdered: NSOrderedSet?
} }

View File

@@ -2,7 +2,7 @@
// TransactionTests.swift // TransactionTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import Foundation
import XCTest import XCTest
@testable @testable
@@ -69,9 +70,9 @@ final class TransactionTests: BaseTestCase {
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext) XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext) XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
@@ -84,14 +85,14 @@ final class TransactionTests: BaseTestCase {
do { do {
let updateExpectation = self.expectation(description: "update") let updateExpectation = self.expectation(description: "update")
let hasChanges: Bool = try! stack.perform( let hasChanges: Bool = try stack.perform(
synchronous: { (transaction) in synchronous: { (transaction) in
defer { defer {
updateExpectation.fulfill() updateExpectation.fulfill()
} }
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
// TODO: convert fetch methods to throwing methods // TODO: convert fetch methods to throwing methods
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -107,9 +108,9 @@ final class TransactionTests: BaseTestCase {
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertEqual(object?.testString, "string1_edit")
@@ -128,7 +129,7 @@ final class TransactionTests: BaseTestCase {
deleteExpectation.fulfill() deleteExpectation.fulfill()
} }
let object = transaction.fetchOne(From<TestEntity1>()) let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object) transaction.delete(object)
return transaction.hasChanges return transaction.hasChanges
} }
@@ -141,9 +142,9 @@ final class TransactionTests: BaseTestCase {
} }
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object) XCTAssertNil(object)
} }
} }
@@ -184,10 +185,10 @@ final class TransactionTests: BaseTestCase {
} }
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1")) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1") XCTAssertEqual(object?.testString, "string1")
@@ -206,7 +207,7 @@ final class TransactionTests: BaseTestCase {
updateExpectation.fulfill() updateExpectation.fulfill()
} }
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else { guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -226,10 +227,10 @@ final class TransactionTests: BaseTestCase {
} }
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1")) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertEqual(object?.testString, "string1_edit")
@@ -248,7 +249,7 @@ final class TransactionTests: BaseTestCase {
deleteExpectation.fulfill() deleteExpectation.fulfill()
} }
let object = transaction.fetchOne(From<TestEntity1>("Config1")) let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object) transaction.delete(object)
return transaction.hasChanges return transaction.hasChanges
@@ -262,8 +263,8 @@ final class TransactionTests: BaseTestCase {
} }
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
} }
} }
} }
@@ -294,17 +295,17 @@ final class TransactionTests: BaseTestCase {
) )
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object) XCTAssertNil(object)
} }
let testDate = Date() let testDate = Date()
do { do {
let createExpectation = self.expectation(description: "create") let createExpectation = self.expectation(description: "create")
let dataPrepared: Void? = try? stack.perform( try stack.perform(
synchronous: { (transaction) in synchronous: { (transaction) -> Void in
let object = transaction.create(Into<TestEntity1>()) let object = transaction.create(Into<TestEntity1>())
object.testEntityID = NSNumber(value: 1) object.testEntityID = NSNumber(value: 1)
@@ -313,10 +314,7 @@ final class TransactionTests: BaseTestCase {
object.testDate = testDate object.testDate = testDate
} }
) )
if dataPrepared != nil { createExpectation.fulfill()
createExpectation.fulfill()
}
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
} }
do { do {
@@ -329,7 +327,7 @@ final class TransactionTests: BaseTestCase {
updateDiscardExpectation.fulfill() updateDiscardExpectation.fulfill()
} }
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -343,9 +341,9 @@ final class TransactionTests: BaseTestCase {
) )
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1") XCTAssertEqual(object?.testString, "string1")
@@ -362,7 +360,7 @@ final class TransactionTests: BaseTestCase {
deleteDiscardExpectation.fulfill() deleteDiscardExpectation.fulfill()
} }
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -374,9 +372,9 @@ final class TransactionTests: BaseTestCase {
) )
self.checkExpectationsImmediately() self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1") XCTAssertEqual(object?.testString, "string1")
@@ -386,8 +384,6 @@ final class TransactionTests: BaseTestCase {
} }
} }
@available(OSX 10.12, *)
@objc @objc
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() { dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
@@ -396,15 +392,15 @@ final class TransactionTests: BaseTestCase {
let observer = TestListObserver() let observer = TestListObserver()
let monitor = stack.monitorList( let monitor = stack.monitorList(
From<TestEntity1>(), From<TestEntity1>(),
OrderBy(.ascending("testEntityID")) OrderBy<TestEntity1>(.ascending("testEntityID"))
) )
monitor.addObserver(observer) monitor.addObserver(observer)
XCTAssertFalse(monitor.hasObjects()) XCTAssertFalse(monitor.hasObjects())
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorWillChange:", forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -417,8 +413,8 @@ final class TransactionTests: BaseTestCase {
return events == 0 return events == 0
} }
) )
let didInsertObjectExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitor:didInsertObject:toIndexPath:", forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -431,9 +427,9 @@ final class TransactionTests: BaseTestCase {
["indexPath", "object"] ["indexPath", "object"]
) )
let indexPath = userInfo?["indexPath"] as? NSIndexPath let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.index(atPosition: 0), 0) XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(indexPath?.item, 0)
let object = userInfo?["object"] as? TestEntity1 let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -447,8 +443,8 @@ final class TransactionTests: BaseTestCase {
return events == 1 return events == 1
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: "listMonitorDidChange:", forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -520,19 +516,26 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) do {
let object = stack.fetchOne(From<TestEntity1>()) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext) XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testDate, testDate) XCTAssertEqual(object?.testString, "string1")
createExpectation.fulfill() XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -546,7 +549,7 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -560,16 +563,23 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) do {
let object = stack.fetchOne(From<TestEntity1>()) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertNotNil(object)
XCTAssertEqual(object?.testNumber, 200) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testDate, Date.distantFuture) XCTAssertEqual(object?.testString, "string1_edit")
updateExpectation.fulfill() XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -583,7 +593,7 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
let object = transaction.fetchOne(From<TestEntity1>()) let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object) transaction.delete(object)
return transaction.hasChanges return transaction.hasChanges
@@ -591,12 +601,19 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) do {
let object = stack.fetchOne(From<TestEntity1>()) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(object)
deleteExpectation.fulfill() let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object)
deleteExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -604,8 +621,8 @@ final class TransactionTests: BaseTestCase {
} }
) )
} }
self.waitAndCheckExpectations()
} }
self.waitAndCheckExpectations()
} }
@objc @objc
@@ -631,17 +648,24 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) do {
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
let object = stack.fetchOne(From<TestEntity1>("Config1")) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertEqual(object?.testString, "string1") XCTAssertNotNil(object)
XCTAssertEqual(object?.testNumber, 100) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testDate, testDate) XCTAssertEqual(object?.testString, "string1")
createExpectation.fulfill() XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -655,7 +679,7 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else { guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -669,17 +693,24 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) do {
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
let object = stack.fetchOne(From<TestEntity1>("Config1")) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertNotNil(object)
XCTAssertEqual(object?.testNumber, 200) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testDate, Date.distantFuture) XCTAssertEqual(object?.testString, "string1_edit")
updateExpectation.fulfill() XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -693,7 +724,7 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
let object = transaction.fetchOne(From<TestEntity1>("Config1")) let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object) transaction.delete(object)
return transaction.hasChanges return transaction.hasChanges
@@ -701,11 +732,21 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in success: { (hasChanges) in
XCTAssertTrue(hasChanges) XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0) do {
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
let configCount = try stack.fetchCount(From<TestEntity1>("Config1"))
deleteExpectation.fulfill() XCTAssertEqual(configCount, 0)
let defaultCount = try stack.fetchCount(From<TestEntity1>(nil))
XCTAssertEqual(defaultCount, 0)
deleteExpectation.fulfill()
}
catch {
XCTFail()
}
}, },
failure: { _ in failure: { _ in
@@ -713,8 +754,8 @@ final class TransactionTests: BaseTestCase {
} }
) )
} }
self.waitAndCheckExpectations()
} }
self.waitAndCheckExpectations()
} }
@objc @objc
@@ -737,7 +778,7 @@ final class TransactionTests: BaseTestCase {
createDiscardExpectation.fulfill() createDiscardExpectation.fulfill()
try transaction.cancel() try transaction.cancel()
}, },
success: { success: { _ in
XCTFail() XCTFail()
}, },
@@ -754,8 +795,8 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>())) XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
let object = transaction.create(Into<TestEntity1>()) let object = transaction.create(Into<TestEntity1>())
object.testEntityID = NSNumber(value: 1) object.testEntityID = NSNumber(value: 1)
@@ -782,7 +823,7 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Void in asynchronous: { (transaction) -> Void in
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
return return
@@ -795,7 +836,7 @@ final class TransactionTests: BaseTestCase {
try transaction.cancel() try transaction.cancel()
}, },
success: { success: { _ in
XCTFail() XCTFail()
}, },
@@ -811,9 +852,9 @@ final class TransactionTests: BaseTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Void in asynchronous: { (transaction) -> Void in
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
try transaction.cancel() try transaction.cancel()
@@ -828,27 +869,34 @@ final class TransactionTests: BaseTestCase {
try transaction.cancel() try transaction.cancel()
}, },
success: { success: { _ in
XCTFail() XCTFail()
}, },
failure: { (error) in failure: { (error) in
XCTAssertEqual(error, CoreStoreError.userCancelled) XCTAssertEqual(error, CoreStoreError.userCancelled)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) do {
let object = stack.fetchOne(From<TestEntity1>()) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertEqual(object?.testString, "string1") XCTAssertNotNil(object)
XCTAssertEqual(object?.testNumber, 100) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testDate, testDate) XCTAssertEqual(object?.testString, "string1")
deleteDiscardExpectation.fulfill() XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
deleteDiscardExpectation.fulfill()
}
catch {
XCTFail()
}
} }
) )
} }
self.waitAndCheckExpectations()
} }
self.waitAndCheckExpectations()
} }
@objc @objc
@@ -878,9 +926,9 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext) XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext) XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
@@ -897,7 +945,7 @@ final class TransactionTests: BaseTestCase {
} }
do { do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
return return
@@ -911,9 +959,9 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>()) let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertEqual(object?.testString, "string1_edit")
@@ -927,7 +975,7 @@ final class TransactionTests: BaseTestCase {
} }
do { do {
let object = transaction.fetchOne(From<TestEntity1>()) let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object) transaction.delete(object)
do { do {
@@ -935,8 +983,8 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(stack.fetchOne(From<TestEntity1>())) XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
} }
catch { catch {
@@ -967,10 +1015,10 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1")) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1") XCTAssertEqual(object?.testString, "string1")
@@ -984,7 +1032,7 @@ final class TransactionTests: BaseTestCase {
} }
do { do {
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else { guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail() XCTFail()
return return
@@ -998,10 +1046,10 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1")) let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object) XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit") XCTAssertEqual(object?.testString, "string1_edit")
@@ -1015,7 +1063,7 @@ final class TransactionTests: BaseTestCase {
} }
do { do {
let object = transaction.fetchOne(From<TestEntity1>("Config1")) let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object) transaction.delete(object)
do { do {
@@ -1023,8 +1071,8 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges) XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait() try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
} }
catch { catch {
@@ -1050,11 +1098,11 @@ final class TransactionTests: BaseTestCase {
transaction.rollback() transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>())) XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(stack.fetchOne(From<TestEntity1>())) XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
} }
let testDate = Date() let testDate = Date()
@@ -1079,7 +1127,7 @@ final class TransactionTests: BaseTestCase {
do { do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
return return
@@ -1090,8 +1138,8 @@ final class TransactionTests: BaseTestCase {
transaction.rollback() transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
if let object = transaction.fetchOne(From<TestEntity1>()) { if let object = try transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1") XCTAssertEqual(object.testString, "string1")
@@ -1103,8 +1151,8 @@ final class TransactionTests: BaseTestCase {
XCTFail() XCTFail()
} }
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
if let object = stack.fetchOne(From<TestEntity1>()) { if let object = try stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1") XCTAssertEqual(object.testString, "string1")
@@ -1119,7 +1167,7 @@ final class TransactionTests: BaseTestCase {
do { do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else { guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail() XCTFail()
return return
@@ -1128,8 +1176,8 @@ final class TransactionTests: BaseTestCase {
transaction.rollback() transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
if let object = transaction.fetchOne(From<TestEntity1>()) { if let object = try transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1") XCTAssertEqual(object.testString, "string1")
@@ -1141,8 +1189,8 @@ final class TransactionTests: BaseTestCase {
XCTFail() XCTFail()
} }
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1) XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
if let object = stack.fetchOne(From<TestEntity1>()) { if let object = try stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1)) XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1") XCTAssertEqual(object.testString, "string1")

View File

@@ -2,7 +2,7 @@
// TweakTests.swift // TweakTests.swift
// CoreStore // CoreStore
// //
// Copyright © 2016 John Rommel Estropia // Copyright © 2018 John Rommel Estropia
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
@@ -23,6 +23,7 @@
// SOFTWARE. // SOFTWARE.
// //
import CoreData
import XCTest import XCTest
@testable @testable
@@ -43,7 +44,7 @@ final class TweakTests: XCTestCase {
$0.fetchLimit = 200 $0.fetchLimit = 200
$0.predicate = predicate $0.predicate = predicate
} }
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
tweak.applyToFetchRequest(request) tweak.applyToFetchRequest(request)
XCTAssertEqual(request.fetchOffset, 100) XCTAssertEqual(request.fetchOffset, 100)
XCTAssertEqual(request.fetchLimit, 200) XCTAssertEqual(request.fetchLimit, 200)

View File

@@ -0,0 +1,55 @@
//
// VersionLockTests.swift
// CoreStore
//
// Copyright © 2018 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: - VersionLockTests
final class VersionLockTests: XCTestCase {
@objc
dynamic func test_ThatVersionLocksProduceCorrectHashes() {
let versionLock: VersionLock = [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
]
XCTAssertEqual(
versionLock.description,
"""
[
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
]
"""
)
}
}

Some files were not shown because too many files have changed in this diff Show More