Compare commits

..

346 Commits

Author SHA1 Message Date
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
845 changed files with 602756 additions and 26562 deletions

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 @@
4.0

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,50 +0,0 @@
language: objective-c
osx_image: xcode9
sudo: false
git:
submodules: false
notifications:
email: false
env:
global:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
matrix:
- DESTINATION="OS=11.0,name=iPhone 8" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.13 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=4.0,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=11.0,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 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.26.0/Carthage.pkg"
- sudo installer -pkg "Carthage.pkg" -target /
- rm "Carthage.pkg"
- npm install ios-sim -g
- ios-sim start --devicetypeid "com.apple.CoreSimulator.SimDeviceType.iPhone-8, 11.0"
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 "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Release ONLY_ACTIVE_ARCH=NO build | 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 = "5.0.0" 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 = "13.0"
ts.osx.deployment_target = "10.15"
ts.tvos.deployment_target = "13.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 = "0900" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -26,8 +26,16 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
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">
@@ -40,23 +48,11 @@
</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"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
@@ -72,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 = "0900" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -40,20 +40,7 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
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"
@@ -70,12 +57,23 @@
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"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
@@ -91,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 = "0900" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -26,8 +26,16 @@
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
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">
@@ -40,23 +48,11 @@
</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"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
@@ -72,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 = "0900" LastUpgradeVersion = "1600"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
@@ -20,24 +20,44 @@
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
buildConfiguration = "Debug" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
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"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0" launchStyle = "0"
useCustomWorkingDirectory = "NO" useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO" ignoresPersistentStateOnLaunch = "NO"
@@ -53,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,556 +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 = 0900;
ORGANIZATIONNAME = "John Rommel Estropia";
TargetAttributes = {
B54AAD481AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
LastSwiftMigration = 0900;
};
};
};
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_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = 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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
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";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
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_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = 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_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
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;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
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_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.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_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.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,27 +0,0 @@
//
// AppDelegate.swift
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
//
import UIKit
// 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,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16F73" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" 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" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
</entity>
<configuration name="FetchingAndQueryingDemo">
<memberEntity name="TimeZone"/>
</configuration>
<configuration name="TransactionsDemo">
<memberEntity name="Place"/>
</configuration>
<elements>
<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,319 +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(\.name))
)!
}
),
(
title: "Time Zones in Asia",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"Asia"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
}
),
(
title: "Time Zones in America and Europe",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America",
#keyPath(TimeZone.name),
"Europe"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
}
),
(
title: "All Time Zones Except America",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
}
),
(
title: "Time Zones with Summer Time",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(\.hasDaylightSavingTime == true)
.orderBy(.ascending(\.name))
)!
}
)
]
private let queryingItems: [(title: String, query: () -> Any)] = [
(
title: "Number of Time Zones",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(NSNumber.self, .count(\.name))
)! as Any
}
),
(
title: "Abbreviation For Tokyo's Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(String.self, .attribute(\.abbreviation))
.where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
)! as Any
}
),
(
title: "All Abbreviations",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.attribute(\.name),
.attribute(\.abbreviation)
)
.orderBy(.ascending(\.name))
)!
}
),
(
title: "Number of Countries per Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.abbreviation),
.attribute(\.abbreviation)
)
.groupBy(\.abbreviation)
.orderBy(
.ascending(\.secondsFromGMT),
.ascending(\.name)
)
)!
}
),
(
title: "Number of Countries with Summer Time",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.hasDaylightSavingTime, as: "numberOfCountries"),
.attribute(\.hasDaylightSavingTime)
)
.groupBy(\.hasDaylightSavingTime)
.orderBy(
.descending(\.hasDaylightSavingTime),
.ascending(\.name)
)
)!
}
)
]
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,328 +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
struct ColorsDemo {
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<Palette> {
switch self {
case .all: return .init()
case .light: return (\Palette.brightness >= 0.9)
case .dark: return (\Palette.brightness <= 0.4)
}
}
}
static var filter = Filter.all {
didSet {
self.palettes.refetch(
self.filter.whereClause(),
OrderBy<Palette>(.ascending(\.hue))
)
}
}
static let stack: DataStack = {
return DataStack(
CoreStoreSchema(
modelVersion: "ColorsDemo",
entities: [
Entity<Palette>("Palette"),
],
versionLock: [
"Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f]
]
)
)
}()
static let palettes: ListMonitor<Palette> = {
try! ColorsDemo.stack.addStorageAndWait(
SQLiteStore(
fileName: "ColorsDemo.sqlite",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
return ColorsDemo.stack.monitorSectionedList(
From<Palette>()
.sectionBy(\.colorName)
.orderBy(.ascending(\.hue))
)
}()
}
// MARK: - ListObserverDemoViewController
class ListObserverDemoViewController: UITableViewController, ListSectionObserver {
// MARK: NSObject
deinit {
ColorsDemo.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: ColorsDemo.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
ColorsDemo.palettes.addObserver(self)
self.setTable(enabled: !ColorsDemo.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 ColorsDemo.palettes.numberOfSections()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ColorsDemo.palettes.numberOfObjectsInSection(section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
let palette = ColorsDemo.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: ColorsDemo.palettes[indexPath]
)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
switch editingStyle {
case .delete:
let palette = ColorsDemo.palettes[indexPath]
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.delete(palette)
},
completion: { _ in }
)
default:
break
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ColorsDemo.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 = ColorsDemo.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 = ColorsDemo.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?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
}
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.filter = ColorsDemo.filter.next()
}
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
},
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 = ColorsDemo.stack.monitorObject(palette)
}
else {
self.monitor = nil
}
}
}
// MARK: NSObject
deinit {
self.monitor?.removeObserver(self)
}
// MARK: UIViewController
required init?(coder aDecoder: NSCoder) {
if let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
else {
_ = try? ColorsDemo.stack.perform(
synchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
}
)
let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
self.monitor = ColorsDemo.stack.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<KeyPathString>) {
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
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.hue .= Int(hue)
}
},
completion: { _ in }
)
}
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
let saturation = self.saturationSlider?.value ?? 0
ColorsDemo.stack.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
ColorsDemo.stack.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?) {
ColorsDemo.stack.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.value
let color = palette.color
self.colorNameLabel?.textColor = color
self.colorView?.backgroundColor = color
self.hsbLabel?.text = palette.colorText
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.hue }) == true {
self.hueSlider?.value = Float(palette.hue.value)
}
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.saturation }) == true {
self.saturationSlider?.value = palette.saturation.value
}
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.brightness }) == true {
self.brightnessSlider?.value = palette.brightness.value
}
}
}

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,78 +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
final class Palette: CoreStoreObject {
let hue = Value.Required<Int>("hue", initial: 0)
let saturation = Value.Required<Float>("saturation", initial: 0)
let brightness = Value.Required<Float>("brightness", initial: 0)
let colorName = Value.Optional<String>(
"colorName",
isTransient: true,
customGetter: Palette.getColorName
)
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
if let colorName = partialObject.primitiveValue(for: { $0.colorName }) {
return colorName
}
let colorName: String
switch partialObject.value(for: { $0.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"
}
partialObject.setPrimitiveValue(colorName, for: { $0.colorName })
return colorName
}
}
extension Palette {
var color: UIColor {
return UIColor(
hue: CGFloat(self.hue.value) / 360.0,
saturation: CGFloat(self.saturation.value),
brightness: CGFloat(self.brightness.value),
alpha: 1.0
)
}
var colorText: String {
return "H: \(self.hue.value)˚, S: \(round(self.saturation.value * 100.0))%, B: \(round(self.brightness.value * 100.0))%"
}
func setInitialValues(in transaction: BaseDataTransaction) {
self.hue .= Int(arc4random_uniform(360))
self.saturation .= Float(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<NSManagedObject>(true).applyToFetchRequest(request)
Where<NSManagedObject>(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<Place>())
}
default:
return
}
}
}

View File

@@ -1,445 +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(xcodeModelName: "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)
}
}
func listMonitorDidRefetch(_ monitor: ListMonitor<NSManagedObject>) {
self.listMonitorDidChange(monitor)
}
// 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(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
),
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
)
),
(
label: "Model V2",
entityType: OrganismV2.self,
schemaHistory: SchemaHistory(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: [
"MigrationDemo": "MigrationDemoV2",
"MigrationDemoV3": "MigrationDemoV2"
]
),
migrationChain: [
"MigrationDemo": "MigrationDemoV2",
"MigrationDemoV3": "MigrationDemoV2"
]
)
),
(
label: "Model V3",
entityType: OrganismV3.self,
schemaHistory: SchemaHistory(
XcodeDataModelSchema.from(
modelName: "MigrationDemo",
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
),
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<NSManagedObject>(model.entityType)
.select(Int.self, .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: { (arg) -> Bool in
let (_, _, schemaHistory) = arg
return schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
}
)!
self._dataStack = dataStack
let listMonitor = dataStack.monitorList(
From(model.entityType),
OrderBy<NSManagedObject>(.descending(#keyPath(OrganismV1.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(xcodeModelName: "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(xcodeModelName: "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<KeyPathString>) {
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(
xcodeModelName: "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,7 +2,7 @@
// BaseTestDataTestCase.swift // BaseTestDataTestCase.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
@@ -34,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,257 +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]
initWithXcodeModelName:@"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]
initWithXcodeModelName:@"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];
}
@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
@@ -64,7 +66,7 @@ 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>(),

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,81 +28,158 @@ import XCTest
@testable @testable
import CoreStore import CoreStore
#if os(OSX) #if os(macOS)
typealias Color = NSColor typealias Color = NSColor
#else #else
typealias Color = UIColor typealias Color = UIColor
#endif #endif
class Animal: CoreStoreObject { class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "Swift") @Field.Stored("species")
let master = Relationship.ToOne<Person>("master") var species: String = "Swift"
let color = Transformable.Optional<Color>("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", initial: 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>( @Field.Stored(
"title", "title",
initial: "Mr.", customSetter: { (object, field, newValue) in
customSetter: Person.setTitle field.primitiveValue = newValue
object.$displayName.primitiveValue = nil
}
) )
var title: String = "Mr."
let name = Value.Required<String>(
@Field.Stored(
"name", "name",
initial: "", customSetter: { (object, field, newValue) in
customSetter: Person.setName field.primitiveValue = newValue
object.$displayName.primitiveValue = nil
}
) )
var name: String = ""
let displayName = Value.Optional<String>(
@Field.Virtual(
"displayName", "displayName",
isTransient: true, customGetter: Person.getDisplayName(_:_:),
customGetter: Person.getDisplayName(_:),
affectedByKeyPaths: Person.keyPathsAffectingDisplayName() affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
) )
var displayName: String?
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
@Field.Virtual(
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) { "customType",
customGetter: { (object, field) in
partialObject.setPrimitiveValue(newValue, for: { $0.title })
partialObject.setPrimitiveValue(nil, for: { $0.displayName }) if let value = field.primitiveValue {
}
return value
private static func setName(_ partialObject: PartialObject<Person>, _ newValue: String) { }
let value = CustomType()
partialObject.setPrimitiveValue(newValue, for: { $0.name }) field.primitiveValue = value
partialObject.setPrimitiveValue(nil, for: { $0.displayName }) return value
}
static func getDisplayName(_ partialObject: PartialObject<Person>) -> String? {
if let displayName = partialObject.primitiveValue(for: { $0.displayName }) {
return displayName
} }
let title = partialObject.value(for: { $0.title }) )
let name = partialObject.value(for: { $0.name }) var customField: CustomType
let displayName = "\(title) \(name)"
partialObject.setPrimitiveValue(displayName, for: { $0.displayName }) @Field.Coded(
return displayName "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
} }
static func keyPathsAffectingDisplayName() -> Set<String> { private static func keyPathsAffectingDisplayName() -> Set<String> {
return [ return [
String(keyPath: \Person.title), String(keyPath: \Person.$title),
String(keyPath: \Person.name) String(keyPath: \Person.$name)
] ]
} }
} }
@@ -120,62 +197,152 @@ class DynamicModelTests: BaseTestDataTestCase {
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 = String(keyPath: \Animal.species) let k1 = String(keyPath: \Animal.$species)
XCTAssertEqual(k1, "species") XCTAssertEqual(k1, "species")
let k2 = String(keyPath: \Dog.species) let k2 = String(keyPath: \Dog.$species)
XCTAssertEqual(k2, "species") XCTAssertEqual(k2, "species")
let k3 = String(keyPath: \Dog.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, Color.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))
XCTAssertEqual( XCTAssertEqual(
type(of: person.rawObject!).keyPathsForValuesAffectingValue(forKey: "displayName"), person.rawObject!
.runtimeType()
.keyPathsForValuesAffectingValue(forKey: "displayName"),
["title", "name"] ["title", "name"]
) )
person.name .= "Joe" person.name = "Joe"
XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe") XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe") XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
@@ -183,22 +350,66 @@ class DynamicModelTests: BaseTestDataTestCase {
person.rawObject!.setValue("AAAA", forKey: "displayName") person.rawObject!.setValue("AAAA", forKey: "displayName")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA") XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
person.name .= "John" person.name = "John"
XCTAssertEqual(person.name.value, "John") XCTAssertEqual(person.name, "John")
XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter XCTAssertEqual(person.displayName, "Mr. John") // Custom getter
person.title .= "Sir" let personSnapshot1 = person.asSnapshot(in: transaction)!
XCTAssertEqual(person.displayName.value, "Sir John") XCTAssertEqual(person.name, personSnapshot1.$name)
XCTAssertEqual(person.title, personSnapshot1.$title)
XCTAssertEqual(person.displayName, personSnapshot1.$displayName)
XCTAssertEqual(person.job, personSnapshot1.$job)
person.pets.value.insert(dog) 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: { _ in 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
@@ -209,56 +420,67 @@ class DynamicModelTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) in asynchronous: { (transaction) in
let p1 = Where<Animal>({ $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 = Where<Dog>({ $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>().where(\.nickname == "Spot")) 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 = Where<Dog>({ $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)
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>() From<Dog>()
.where(\Animal.species == "Dog" && \.age == 10) .where(\Animal.$species == "Dog" && \Dog.$age == 10)
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>() From<Dog>()
.where(\.age == 10 && \Animal.species == "Dog") .where(\Dog.$age == 10 && \Animal.$species == "Dog")
.orderBy(.ascending({ $0.species })) .orderBy(.ascending({ $0.$species }))
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>(), From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 }) Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>(), From<Dog>(),
Where<Dog>({ $0.species == "Dog" && $0.age == 10 }) Where<Dog>({ $0.$species == "Dog" && $0.$age == 10 })
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>(), From<Dog>(),
Where<Dog>({ $0.age == 10 && $0.species == "Dog" }) Where<Dog>({ $0.$age == 10 && $0.$species == "Dog" })
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>(), From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 }) Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
) )
_ = transaction.fetchAll( _ = try transaction.fetchAll(
From<Dog>(), From<Dog>(),
(\Dog.age > 10 && \Dog.age <= 15) (\Dog.$age > 10 && \Dog.$age <= 15)
) )
}, },
success: { _ in success: { _ in
@@ -270,15 +492,20 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTFail() XCTFail()
} }
) )
self.waitAndCheckExpectations() }
self.waitForExpectations(timeout: 10, handler: { _ in })
self.addTeardownBlock {
dataStack.unsafeRemoveAllPersistentStoresAndWait()
} }
} }
@objc @objc
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() { dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \Animal.species), "species") XCTAssertEqual(String(keyPath: \Animal.$species), "species")
XCTAssertEqual(String(keyPath: \Dog.species), "species") XCTAssertEqual(String(keyPath: \Dog.$species), "species")
} }
@nonobjc @nonobjc
@@ -292,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)
@@ -88,7 +84,7 @@ final class ErrorTests: XCTestCase {
let schemaHistory = SchemaHistory( let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from( XcodeDataModelSchema.from(
modelName: "Model", modelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
) )
let version = "1.0.0" let version = "1.0.0"
@@ -102,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)
@@ -127,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)
@@ -159,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
@@ -68,8 +69,8 @@ final class GroupByTests: BaseTestCase {
let groupBy = GroupBy<NSManagedObject>(#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
@@ -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<TestEntity1>(#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]
@@ -618,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<TestEntity1>(#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)
@@ -657,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<TestEntity1>(#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()
} }
@@ -710,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))
@@ -735,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))
@@ -745,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<TestEntity1>(#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)
} }
} }
@@ -799,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]
@@ -864,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<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))) XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#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()
@@ -910,7 +906,7 @@ class ImportTests: BaseTestDataTestCase {
errorExpectation.fulfill() errorExpectation.fulfill()
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#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)
@@ -951,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<TestEntity1>(#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))
@@ -963,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<TestEntity1>(#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()
@@ -1018,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]
@@ -1032,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<TestEntity1>(#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
@@ -53,7 +53,7 @@ class ListObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -67,7 +67,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didInsertSectionExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "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,7 +87,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 return events == 1
} }
) )
let didInsertObjectExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "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,7 +119,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 2 return events == 2
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -178,13 +178,13 @@ class ListObserverTests: BaseTestDataTestCase {
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: NSNotification.Name(rawValue: "listMonitorWillChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -199,7 +199,7 @@ class ListObserverTests: BaseTestDataTestCase {
} }
) )
let didUpdateObjectExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"), forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -213,14 +213,14 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"] ["indexPath", "object"]
) )
let indexPath = userInfo?["indexPath"] as? NSIndexPath let indexPath = userInfo?["indexPath"] as? IndexPath
let object = userInfo?["object"] as? TestEntity1 let object = userInfo?["object"] as? TestEntity1
switch object?.testEntityID { switch object?.testEntityID {
case NSNumber(value: 101)?: case NSNumber(value: 101)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 1) XCTAssertEqual(indexPath?.section, 1)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(indexPath?.item, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 11)) XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
@@ -230,8 +230,8 @@ class ListObserverTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!) XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
case NSNumber(value: 102)?: case NSNumber(value: 102)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 0) XCTAssertEqual(indexPath?.section, 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(indexPath?.item, 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false)) XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22)) XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
@@ -250,7 +250,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 || events == 2 return events == 1 || events == 2
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -268,7 +268,7 @@ 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<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
@@ -282,7 +282,7 @@ class ListObserverTests: BaseTestDataTestCase {
XCTFail() XCTFail()
} }
if let object = transaction.fetchOne( if let object = try transaction.fetchOne(
From<TestEntity1>(), From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
@@ -329,7 +329,7 @@ class ListObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -343,7 +343,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didMoveObjectExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"), forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -357,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))
@@ -376,7 +376,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 return events == 1
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -394,7 +394,7 @@ 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<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
@@ -437,7 +437,7 @@ class ListObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -451,7 +451,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didUpdateObjectExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"), forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -465,10 +465,10 @@ class ListObserverTests: BaseTestDataTestCase {
["indexPath", "object"] ["indexPath", "object"]
) )
let indexPath = userInfo?["indexPath"] as? NSIndexPath let indexPath = userInfo?["indexPath"] as? IndexPath
XCTAssertEqual(indexPath?.section, 0) XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1) XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
let object = userInfo?["object"] as? TestEntity1 let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true) XCTAssertEqual(object?.isDeleted, true)
@@ -480,7 +480,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 1 || events == 2 return events == 1 || events == 2
} }
) )
let didDeleteSectionExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"), forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -508,7 +508,7 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 3 return events == 3
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -526,7 +526,7 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform( stack.perform(
asynchronous: { (transaction) -> Bool in asynchronous: { (transaction) -> Bool in
let count = transaction.deleteAll( let count = try transaction.deleteAll(
From<TestEntity1>(), From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false) Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
) )
@@ -551,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,7 +40,7 @@ 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<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
@@ -57,7 +56,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let willUpdateExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"), forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -74,7 +73,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
return events == 0 return events == 0
} }
) )
let didUpdateExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"), forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -138,7 +137,7 @@ 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<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
@@ -154,7 +153,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0 var events = 0
let didDeleteExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "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

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
@@ -179,7 +180,7 @@ final class OrderByTests: XCTestCase {
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() { dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
let orderBy = OrderBy<NSManagedObject>(.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)

View File

@@ -2,7 +2,7 @@
// QueryTests.swift // QueryTests.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
@@ -47,7 +48,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(#keyPath(TestEntity1.testBoolean)), Select<TestEntity1, Bool>(#keyPath(TestEntity1.testBoolean)),
queryClauses queryClauses
@@ -57,7 +58,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Int8>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -67,7 +68,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Int16>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -77,7 +78,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Int32>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -87,7 +88,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Int64>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -97,7 +98,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Int>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -107,7 +108,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Double>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -117,7 +118,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, Float>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -127,7 +128,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(#keyPath(TestEntity1.testNumber)), Select<TestEntity1, NSNumber>(#keyPath(TestEntity1.testNumber)),
queryClauses queryClauses
@@ -137,7 +138,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(#keyPath(TestEntity1.testDecimal)), Select<TestEntity1, NSDecimalNumber>(#keyPath(TestEntity1.testDecimal)),
queryClauses queryClauses
@@ -147,7 +148,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(#keyPath(TestEntity1.testString)), Select<TestEntity1, String>(#keyPath(TestEntity1.testString)),
queryClauses queryClauses
@@ -157,7 +158,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(#keyPath(TestEntity1.testString)), Select<TestEntity1, NSString>(#keyPath(TestEntity1.testString)),
queryClauses queryClauses
@@ -167,7 +168,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(#keyPath(TestEntity1.testData)), Select<TestEntity1, Data>(#keyPath(TestEntity1.testData)),
queryClauses queryClauses
@@ -177,7 +178,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(#keyPath(TestEntity1.testData)), Select<TestEntity1, NSData>(#keyPath(TestEntity1.testData)),
queryClauses queryClauses
@@ -187,7 +188,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(#keyPath(TestEntity1.testDate)), Select<TestEntity1, Date>(#keyPath(TestEntity1.testDate)),
queryClauses queryClauses
@@ -197,7 +198,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(#keyPath(TestEntity1.testDate)), Select<TestEntity1, NSDate>(#keyPath(TestEntity1.testDate)),
queryClauses queryClauses
@@ -207,7 +208,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testDate)), Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testDate)),
queryClauses queryClauses
@@ -232,7 +233,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.average(#keyPath(TestEntity1.testBoolean))), Select<TestEntity1, Bool>(.average(#keyPath(TestEntity1.testBoolean))),
queryClauses queryClauses
@@ -242,7 +243,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int8>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -252,7 +253,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int16>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -262,7 +263,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int32>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -272,7 +273,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int64>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -282,7 +283,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -292,7 +293,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Double>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -302,7 +303,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Float>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -312,7 +313,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.average(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, NSNumber>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -322,7 +323,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.average(#keyPath(TestEntity1.testDecimal))), Select<TestEntity1, NSDecimalNumber>(.average(#keyPath(TestEntity1.testDecimal))),
queryClauses queryClauses
@@ -332,7 +333,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.average(#keyPath(TestEntity1.testString))), Select<TestEntity1, String>(.average(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -341,7 +342,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.average(#keyPath(TestEntity1.testString))), Select<TestEntity1, NSString>(.average(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -350,7 +351,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.average(#keyPath(TestEntity1.testData))), Select<TestEntity1, Data>(.average(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -359,7 +360,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.average(#keyPath(TestEntity1.testData))), Select<TestEntity1, NSData>(.average(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -368,7 +369,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.average(#keyPath(TestEntity1.testDate))), Select<TestEntity1, Date>(.average(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -377,7 +378,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.average(#keyPath(TestEntity1.testDate))), Select<TestEntity1, NSDate>(.average(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -386,7 +387,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testEntityID)), Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testEntityID)),
queryClauses queryClauses
@@ -410,7 +411,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.count(#keyPath(TestEntity1.testBoolean))), Select<TestEntity1, Bool>(.count(#keyPath(TestEntity1.testBoolean))),
queryClauses queryClauses
@@ -420,7 +421,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int8>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -430,7 +431,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int16>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -440,7 +441,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int32>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -450,7 +451,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int64>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -460,7 +461,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -470,7 +471,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Double>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -480,7 +481,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Float>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -490,7 +491,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.count(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, NSNumber>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -500,7 +501,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.count(#keyPath(TestEntity1.testDecimal))), Select<TestEntity1, NSDecimalNumber>(.count(#keyPath(TestEntity1.testDecimal))),
queryClauses queryClauses
@@ -509,7 +510,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.count(#keyPath(TestEntity1.testString))), Select<TestEntity1, String>(.count(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -518,7 +519,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.count(#keyPath(TestEntity1.testString))), Select<TestEntity1, NSString>(.count(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -527,7 +528,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.count(#keyPath(TestEntity1.testData))), Select<TestEntity1, Data>(.count(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -536,7 +537,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.count(#keyPath(TestEntity1.testData))), Select<TestEntity1, NSData>(.count(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -545,7 +546,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.count(#keyPath(TestEntity1.testDate))), Select<TestEntity1, Date>(.count(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -554,7 +555,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.count(#keyPath(TestEntity1.testDate))), Select<TestEntity1, NSDate>(.count(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -563,7 +564,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(.count(#keyPath(TestEntity1.testEntityID))), Select<TestEntity1, NSManagedObjectID>(.count(#keyPath(TestEntity1.testEntityID))),
queryClauses queryClauses
@@ -587,7 +588,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.maximum(#keyPath(TestEntity1.testBoolean))), Select<TestEntity1, Bool>(.maximum(#keyPath(TestEntity1.testBoolean))),
queryClauses queryClauses
@@ -597,7 +598,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int8>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -607,7 +608,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int16>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -617,7 +618,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int32>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -627,7 +628,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int64>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -637,7 +638,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -647,7 +648,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Double>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -657,7 +658,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Float>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -667,7 +668,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.maximum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, NSNumber>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -677,7 +678,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.maximum(#keyPath(TestEntity1.testDecimal))), Select<TestEntity1, NSDecimalNumber>(.maximum(#keyPath(TestEntity1.testDecimal))),
queryClauses queryClauses
@@ -687,7 +688,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.maximum(#keyPath(TestEntity1.testString))), Select<TestEntity1, String>(.maximum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -697,7 +698,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.maximum(#keyPath(TestEntity1.testString))), Select<TestEntity1, NSString>(.maximum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -707,7 +708,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.maximum(#keyPath(TestEntity1.testData))), Select<TestEntity1, Data>(.maximum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -717,7 +718,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.maximum(#keyPath(TestEntity1.testData))), Select<TestEntity1, NSData>(.maximum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -727,7 +728,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.maximum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, Date>(.maximum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -737,7 +738,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.maximum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, NSDate>(.maximum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -747,7 +748,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(.maximum(#keyPath(TestEntity1.testEntityID))), Select<TestEntity1, NSManagedObjectID>(.maximum(#keyPath(TestEntity1.testEntityID))),
queryClauses queryClauses
@@ -771,7 +772,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.minimum(#keyPath(TestEntity1.testBoolean))), Select<TestEntity1, Bool>(.minimum(#keyPath(TestEntity1.testBoolean))),
queryClauses queryClauses
@@ -781,7 +782,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int8>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -791,7 +792,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int16>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -801,7 +802,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int32>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -811,7 +812,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int64>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -821,7 +822,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -831,7 +832,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Double>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -841,7 +842,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Float>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -851,7 +852,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.minimum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, NSNumber>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -861,7 +862,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.minimum(#keyPath(TestEntity1.testDecimal))), Select<TestEntity1, NSDecimalNumber>(.minimum(#keyPath(TestEntity1.testDecimal))),
queryClauses queryClauses
@@ -871,7 +872,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.minimum(#keyPath(TestEntity1.testString))), Select<TestEntity1, String>(.minimum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -881,7 +882,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.minimum(#keyPath(TestEntity1.testString))), Select<TestEntity1, NSString>(.minimum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -891,7 +892,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.minimum(#keyPath(TestEntity1.testData))), Select<TestEntity1, Data>(.minimum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -901,7 +902,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.minimum(#keyPath(TestEntity1.testData))), Select<TestEntity1, NSData>(.minimum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -911,7 +912,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.minimum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, Date>(.minimum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -921,7 +922,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.minimum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, NSDate>(.minimum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -931,7 +932,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(.minimum(#keyPath(TestEntity1.testEntityID))), Select<TestEntity1, NSManagedObjectID>(.minimum(#keyPath(TestEntity1.testEntityID))),
queryClauses queryClauses
@@ -955,7 +956,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.sum(#keyPath(TestEntity1.testBoolean))), Select<TestEntity1, Bool>(.sum(#keyPath(TestEntity1.testBoolean))),
queryClauses queryClauses
@@ -965,7 +966,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int8>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -975,7 +976,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int16>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -985,7 +986,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int32>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -995,7 +996,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int64>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -1005,7 +1006,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Int>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -1015,7 +1016,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Double>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -1025,7 +1026,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, Float>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -1035,7 +1036,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.sum(#keyPath(TestEntity1.testNumber))), Select<TestEntity1, NSNumber>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses queryClauses
@@ -1045,7 +1046,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.sum(#keyPath(TestEntity1.testDecimal))), Select<TestEntity1, NSDecimalNumber>(.sum(#keyPath(TestEntity1.testDecimal))),
queryClauses queryClauses
@@ -1055,7 +1056,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.sum(#keyPath(TestEntity1.testString))), Select<TestEntity1, String>(.sum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -1064,7 +1065,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.sum(#keyPath(TestEntity1.testString))), Select<TestEntity1, NSString>(.sum(#keyPath(TestEntity1.testString))),
queryClauses queryClauses
@@ -1073,7 +1074,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.sum(#keyPath(TestEntity1.testData))), Select<TestEntity1, Data>(.sum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -1082,7 +1083,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.sum(#keyPath(TestEntity1.testData))), Select<TestEntity1, NSData>(.sum(#keyPath(TestEntity1.testData))),
queryClauses queryClauses
@@ -1091,7 +1092,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.sum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, Date>(.sum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -1100,7 +1101,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.sum(#keyPath(TestEntity1.testDate))), Select<TestEntity1, NSDate>(.sum(#keyPath(TestEntity1.testDate))),
queryClauses queryClauses
@@ -1109,7 +1110,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(.sum(#keyPath(TestEntity1.testEntityID))), Select<TestEntity1, NSManagedObjectID>(.sum(#keyPath(TestEntity1.testEntityID))),
queryClauses queryClauses
@@ -1133,7 +1134,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Bool>(.objectID()), Select<TestEntity1, Bool>(.objectID()),
queryClauses queryClauses
@@ -1142,7 +1143,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int8>(.objectID()), Select<TestEntity1, Int8>(.objectID()),
queryClauses queryClauses
@@ -1151,7 +1152,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int16>(.objectID()), Select<TestEntity1, Int16>(.objectID()),
queryClauses queryClauses
@@ -1160,7 +1161,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int32>(.objectID()), Select<TestEntity1, Int32>(.objectID()),
queryClauses queryClauses
@@ -1169,7 +1170,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int64>(.objectID()), Select<TestEntity1, Int64>(.objectID()),
queryClauses queryClauses
@@ -1178,7 +1179,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Int>(.objectID()), Select<TestEntity1, Int>(.objectID()),
queryClauses queryClauses
@@ -1187,7 +1188,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Double>(.objectID()), Select<TestEntity1, Double>(.objectID()),
queryClauses queryClauses
@@ -1196,7 +1197,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Float>(.objectID()), Select<TestEntity1, Float>(.objectID()),
queryClauses queryClauses
@@ -1205,7 +1206,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSNumber>(.objectID()), Select<TestEntity1, NSNumber>(.objectID()),
queryClauses queryClauses
@@ -1214,7 +1215,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDecimalNumber>(.objectID()), Select<TestEntity1, NSDecimalNumber>(.objectID()),
queryClauses queryClauses
@@ -1223,7 +1224,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, String>(.objectID()), Select<TestEntity1, String>(.objectID()),
queryClauses queryClauses
@@ -1232,7 +1233,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSString>(.objectID()), Select<TestEntity1, NSString>(.objectID()),
queryClauses queryClauses
@@ -1241,7 +1242,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Data>(.objectID()), Select<TestEntity1, Data>(.objectID()),
queryClauses queryClauses
@@ -1250,7 +1251,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSData>(.objectID()), Select<TestEntity1, NSData>(.objectID()),
queryClauses queryClauses
@@ -1259,7 +1260,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, Date>(.objectID()), Select<TestEntity1, Date>(.objectID()),
queryClauses queryClauses
@@ -1268,7 +1269,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSDate>(.objectID()), Select<TestEntity1, NSDate>(.objectID()),
queryClauses queryClauses
@@ -1277,7 +1278,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let value = stack.queryValue( let value = try stack.queryValue(
from, from,
Select<TestEntity1, NSManagedObjectID>(.objectID()), Select<TestEntity1, NSManagedObjectID>(.objectID()),
queryClauses queryClauses
@@ -1302,7 +1303,7 @@ class QueryTests: BaseTestDataTestCase {
] ]
do { do {
let values = stack.queryAttributes( let values = try stack.queryAttributes(
from, from,
Select<TestEntity1, NSDictionary>( Select<TestEntity1, NSDictionary>(
#keyPath(TestEntity1.testBoolean), #keyPath(TestEntity1.testBoolean),
@@ -1353,7 +1354,7 @@ class QueryTests: BaseTestDataTestCase {
let queryClauses: [QueryClause] = [] let queryClauses: [QueryClause] = []
do { do {
let values = stack.queryAttributes( let values = try stack.queryAttributes(
from, from,
Select<TestEntity1, NSDictionary>( Select<TestEntity1, NSDictionary>(
.sum(#keyPath(TestEntity1.testBoolean)), .sum(#keyPath(TestEntity1.testBoolean)),
@@ -1380,7 +1381,7 @@ class QueryTests: BaseTestDataTestCase {
} }
do { do {
let values = stack.queryAttributes( let values = try stack.queryAttributes(
from, from,
Select( Select(
.sum(#keyPath(TestEntity1.testBoolean), as: "testSum"), .sum(#keyPath(TestEntity1.testBoolean), as: "testSum"),

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
@@ -41,11 +41,14 @@ final class SectionByTests: XCTestCase {
let sectionBy = SectionBy<NSManagedObject>("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<NSManagedObject>("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

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
@@ -39,7 +42,7 @@ class SetupTests: BaseTestDataTestCase {
let schemaHistory = SchemaHistory( let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from( XcodeDataModelSchema.from(
modelName: "Model", modelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
) )
let stack = DataStack(schemaHistory: schemaHistory) let stack = DataStack(schemaHistory: schemaHistory)
@@ -56,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 {
@@ -68,15 +68,12 @@ class SetupTests: BaseTestDataTestCase {
DataStack( DataStack(
xcodeModelName: "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)
} }
} }
@@ -85,7 +82,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack( let stack = DataStack(
xcodeModelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -140,7 +137,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack( let stack = DataStack(
xcodeModelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -208,7 +205,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack( let stack = DataStack(
xcodeModelName: "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)
@@ -227,7 +224,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore() let metadata = try createStore()
let stack = DataStack( let stack = DataStack(
xcodeModelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
try sqliteStore.cs_eraseStorageAndWait( try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata, metadata: metadata,
@@ -260,7 +257,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack( let stack = DataStack(
xcodeModelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
do { do {
@@ -328,9 +325,16 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack( let stack = DataStack(
xcodeModelName: "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))
@@ -347,7 +351,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore() let metadata = try createStore()
let stack = DataStack( let stack = DataStack(
xcodeModelName: "Model", xcodeModelName: "Model",
bundle: Bundle(for: type(of: self)) bundle: Bundle.module
) )
try sqliteStore.cs_eraseStorageAndWait( try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata, metadata: metadata,

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() {
@@ -403,7 +399,7 @@ final class TransactionTests: BaseTestCase {
XCTAssertFalse(monitor.hasObjects()) XCTAssertFalse(monitor.hasObjects())
var events = 0 var events = 0
let willChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"), forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer, object: observer,
handler: { (note) -> Bool in handler: { (note) -> Bool in
@@ -417,7 +413,7 @@ final class TransactionTests: BaseTestCase {
return events == 0 return events == 0
} }
) )
let didInsertObjectExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "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,7 +443,7 @@ final class TransactionTests: BaseTestCase {
return events == 1 return events == 1
} }
) )
let didChangeExpectation = self.expectation( _ = self.expectation(
forNotification: NSNotification.Name(rawValue: "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
@@ -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
@@ -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()
@@ -835,20 +876,27 @@ final class TransactionTests: BaseTestCase {
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]
]
"""
)
}
}

View File

@@ -2,7 +2,7 @@
// WhereTests.swift // WhereTests.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,12 +32,12 @@ import CoreStore
// MARK: - XCTAssertAllEqual // MARK: - XCTAssertAllEqual
private func XCTAssertAllEqual<D>(_ whereClauses: Where<D>...) { private func XCTAssertAllEqual<O>(_ whereClauses: Where<O>...) {
XCTAssertAllEqual(whereClauses) XCTAssertAllEqual(whereClauses)
} }
private func XCTAssertAllEqual<D>(_ whereClauses: [Where<D>]) { private func XCTAssertAllEqual<O>(_ whereClauses: [Where<O>]) {
for i in whereClauses.indices { for i in whereClauses.indices {
@@ -47,6 +48,17 @@ private func XCTAssertAllEqual<D>(_ whereClauses: [Where<D>]) {
} }
} }
private func XCTAssertAllEqual<D: Equatable>(_ items: D...) {
for i in items.indices {
for j in items.indices where j != i {
XCTAssertEqual(items[i], items[j])
}
}
}
//MARK: - WhereTests //MARK: - WhereTests
@@ -55,7 +67,276 @@ final class WhereTests: XCTestCase {
@objc @objc
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() { dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID") XCTAssertAllEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID")
XCTAssertAllEqual(String(keyPath: \Animal.$color), "color")
}
@objc
dynamic func test_ThatExpressions_HaveCorrectKeyPaths() {
do {
do {
XCTAssertAllEqual(
#keyPath(TestEntity1.testToOne.testEntityID),
(\TestEntity1.testToOne ~ \.testEntityID).description,
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
)
XCTAssertAllEqual(
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
)
XCTAssertAllEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
)
}
do {
XCTAssertAllEqual(
"master.pets",
(\Animal.$master ~ \.$pets).description,
String(keyPath: \Animal.$master ~ \.$pets)
)
XCTAssertAllEqual(
"master.pets.species",
(\Animal.$master ~ \.$pets ~ \.$species).description,
String(keyPath: \Animal.$master ~ \.$pets ~ \.$species)
)
XCTAssertAllEqual(
"master.pets.master",
(\Animal.$master ~ \.$pets ~ \.$master).description,
String(keyPath: \Animal.$master ~ \.$pets ~ \.$master)
)
}
}
do {
do {
XCTAssertAllEqual(
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
)
XCTAssertAllEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
)
}
do {
XCTAssertAllEqual(
"master.pets.@count",
(\Animal.$master ~ \.$pets).count().description,
String(keyPath: (\Animal.$master ~ \.$pets).count())
)
}
}
do {
do {
XCTAssertAllEqual(
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
)
XCTAssertAllEqual(
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
)
}
do {
XCTAssertAllEqual(
"ANY master.pets",
(\Animal.$master ~ \.$pets).any().description,
String(keyPath: (\Animal.$master ~ \.$pets).any())
)
XCTAssertAllEqual(
"ANY master.pets.species",
(\Animal.$master ~ \.$pets ~ \.$species).any().description,
String(keyPath: (\Animal.$master ~ \.$pets ~ \.$species).any())
)
}
}
do {
do {
XCTAssertAllEqual(
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
)
XCTAssertAllEqual(
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
)
}
do {
XCTAssertAllEqual(
"ALL master.pets",
(\Animal.$master ~ \.$pets).all().description,
String(keyPath: (\Animal.$master ~ \.$pets).all())
)
XCTAssertAllEqual(
"ALL master.pets.species",
(\Animal.$master ~ \.$pets ~ \.$species).all().description,
String(keyPath: (\Animal.$master ~ \.$pets ~ \.$species).all())
)
}
}
do {
do {
XCTAssertAllEqual(
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
)
XCTAssertAllEqual(
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
)
}
do {
XCTAssertAllEqual(
"NONE master.pets",
(\Animal.$master ~ \.$pets).none().description,
String(keyPath: (\Animal.$master ~ \.$pets).none())
)
XCTAssertAllEqual(
"NONE master.pets.species",
(\Animal.$master ~ \.$pets ~ \.$species).none().description,
String(keyPath: (\Animal.$master ~ \.$pets ~ \.$species).none())
)
}
}
}
@objc
dynamic func test_ThatWhereClauses_CanBeCreatedFromExpressionsCorrectly() {
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testString)) == %@", dummy)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$name) == dummy
let predicate = NSPredicate(format: "master.name == %@", dummy)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToOne.testString)) == %@", dummy)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$spouse ~ \.$name) == dummy
let predicate = NSPredicate(format: "master.spouse.name == %@", dummy)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
do {
let count = 3
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered).count() == count
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToManyUnordered)).@count == %d", count)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$pets).count() == count
let predicate = NSPredicate(format: "master.pets.@count == %d", count)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).any() == dummy
let predicate = NSPredicate(format: "ANY \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$pets ~ \.$species).any() == dummy
let predicate = NSPredicate(format: "ANY master.pets.species == %@", dummy)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).all() == dummy
let predicate = NSPredicate(format: "ALL \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$pets ~ \.$species).all() == dummy
let predicate = NSPredicate(format: "ALL master.pets.species == %@", dummy)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).none() == dummy
let predicate = NSPredicate(format: "NONE \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertAllEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.$master ~ \.$pets ~ \.$species).none() == dummy
let predicate = NSPredicate(format: "NONE master.pets.species == %@", dummy)
XCTAssertAllEqual(whereClause, Where<Animal>(predicate))
XCTAssertAllEqual(whereClause.predicate, predicate)
}
}
} }
@objc @objc
@@ -64,51 +345,51 @@ final class WhereTests: XCTestCase {
do { do {
let whereClause = Where<NSManagedObject>() let whereClause = Where<NSManagedObject>()
XCTAssertEqual(whereClause, Where<NSManagedObject>(true)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(true))
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false)) XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true)) XCTAssertAllEqual(whereClause.predicate, NSPredicate(value: true))
} }
do { do {
let whereClause = Where<NSManagedObject>(true) let whereClause = Where<NSManagedObject>(true)
XCTAssertEqual(whereClause, Where<NSManagedObject>()) XCTAssertAllEqual(whereClause, Where<NSManagedObject>())
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false)) XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true)) XCTAssertAllEqual(whereClause.predicate, NSPredicate(value: true))
} }
do { do {
let predicate = NSPredicate(format: "%K == %@", "key", "value") let predicate = NSPredicate(format: "%K == %@", "key", "value")
let whereClause = Where<NSManagedObject>(predicate) let whereClause = Where<NSManagedObject>(predicate)
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate) XCTAssertAllEqual(whereClause.predicate, predicate)
} }
do { do {
let whereClause = Where<NSManagedObject>("%K == %@", "key", "value") let whereClause = Where<NSManagedObject>("%K == %@", "key", "value")
let predicate = NSPredicate(format: "%K == %@", "key", "value") let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate) XCTAssertAllEqual(whereClause.predicate, predicate)
} }
do { do {
let whereClause = Where<NSManagedObject>("%K == %@", argumentArray: ["key", "value"]) let whereClause = Where<NSManagedObject>("%K == %@", argumentArray: ["key", "value"])
let predicate = NSPredicate(format: "%K == %@", "key", "value") let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate) XCTAssertAllEqual(whereClause.predicate, predicate)
} }
do { do {
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value") let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let predicate = NSPredicate(format: "%K == %@", "key", "value") let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate) XCTAssertAllEqual(whereClause.predicate, predicate)
} }
do { do {
let whereClause = Where<NSManagedObject>("key", isMemberOf: ["value1", "value2", "value3"]) let whereClause = Where<NSManagedObject>("key", isMemberOf: ["value1", "value2", "value3"])
let predicate = NSPredicate(format: "%K IN %@", "key", ["value1", "value2", "value3"]) let predicate = NSPredicate(format: "%K IN %@", "key", ["value1", "value2", "value3"])
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate)) XCTAssertAllEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate) XCTAssertAllEqual(whereClause.predicate, predicate)
} }
} }
@@ -243,8 +524,8 @@ final class WhereTests: XCTestCase {
type: .not, type: .not,
subpredicates: [whereClause1.predicate] subpredicates: [whereClause1.predicate]
) )
XCTAssertEqual(notWhere.predicate, notPredicate) XCTAssertAllEqual(notWhere.predicate, notPredicate)
XCTAssertEqual(notWhere, !whereClause1) XCTAssertAllEqual(notWhere, !whereClause1)
} }
do { do {
@@ -259,8 +540,8 @@ final class WhereTests: XCTestCase {
whereClause3.predicate whereClause3.predicate
] ]
) )
XCTAssertEqual(andWhere.predicate, andPredicate) XCTAssertAllEqual(andWhere.predicate, andPredicate)
XCTAssertEqual(andWhere, whereClause1 && whereClause2 && whereClause3) XCTAssertAllEqual(andWhere, whereClause1 && whereClause2 && whereClause3)
} }
do { do {
@@ -274,8 +555,8 @@ final class WhereTests: XCTestCase {
let unwrappedFinalSomeWhere = andWhere && someWhere! let unwrappedFinalSomeWhere = andWhere && someWhere!
XCTAssertEqual(andWhere.predicate, finalNoneWhere.predicate) XCTAssertAllEqual(andWhere.predicate, finalNoneWhere.predicate)
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate) XCTAssertAllEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
} }
do { do {
@@ -290,8 +571,8 @@ final class WhereTests: XCTestCase {
whereClause3.predicate whereClause3.predicate
] ]
) )
XCTAssertEqual(orWhere.predicate, orPredicate) XCTAssertAllEqual(orWhere.predicate, orPredicate)
XCTAssertEqual(orWhere, whereClause1 || whereClause2 || whereClause3) XCTAssertAllEqual(orWhere, whereClause1 || whereClause2 || whereClause3)
} }
do { do {
@@ -304,8 +585,8 @@ final class WhereTests: XCTestCase {
let finalSomeWhere = orWhere &&? someWhere let finalSomeWhere = orWhere &&? someWhere
let unwrappedFinalSomeWhere = orWhere && someWhere! let unwrappedFinalSomeWhere = orWhere && someWhere!
XCTAssertEqual(orWhere.predicate, finalNoneWhere.predicate) XCTAssertAllEqual(orWhere.predicate, finalNoneWhere.predicate)
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate) XCTAssertAllEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
} }
} }
@@ -314,9 +595,9 @@ final class WhereTests: XCTestCase {
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() { dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value") let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let request = CoreStoreFetchRequest() let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
whereClause.applyToFetchRequest(request) whereClause.applyToFetchRequest(request)
XCTAssertNotNil(request.predicate) XCTAssertNotNil(request.predicate)
XCTAssertEqual(request.predicate, whereClause.predicate) XCTAssertAllEqual(request.predicate, whereClause.predicate)
} }
} }

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