mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-15 13:43:43 +01:00
Compare commits
559 Commits
4.0.0-beta
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a0d27cf34 | ||
|
|
104def4611 | ||
|
|
5dcf29011a | ||
|
|
c9e091a6a4 | ||
|
|
010a79ef6a | ||
|
|
9f9ecb4820 | ||
|
|
3fb2b5927b | ||
|
|
7c2129e38f | ||
|
|
4b6d9a54e7 | ||
|
|
cbf101506c | ||
|
|
9045fbbf1b | ||
|
|
0ee4dc89aa | ||
|
|
30d5e0a64a | ||
|
|
320c6145f8 | ||
|
|
7e37219315 | ||
|
|
d8235cf2e5 | ||
|
|
5cc34ff2e4 | ||
|
|
d4d76c87c9 | ||
|
|
073a1bdee3 | ||
|
|
118bb685fc | ||
|
|
5d0c4bf8ac | ||
|
|
a8bd937c68 | ||
|
|
7988d98b92 | ||
|
|
4b4ae61635 | ||
|
|
535b33ca75 | ||
|
|
b88ade92d6 | ||
|
|
a682f90aff | ||
|
|
f7c3e42009 | ||
|
|
2559375491 | ||
|
|
c923dfc12c | ||
|
|
a5936c1120 | ||
|
|
159448b36d | ||
|
|
7ee91834ab | ||
|
|
8faf44c166 | ||
|
|
7f4cfaf5a0 | ||
|
|
da4ac192db | ||
|
|
e9219682b5 | ||
|
|
6264022ccf | ||
|
|
1ed819b38d | ||
|
|
afddd2edbd | ||
|
|
d1f83badef | ||
|
|
3317867a2f | ||
|
|
f738848e8c | ||
|
|
496145761a | ||
|
|
c54795db5a | ||
|
|
9a026afe40 | ||
|
|
bf10f4668c | ||
|
|
a1a04aaf8a | ||
|
|
4ddfa95140 | ||
|
|
45215c7a18 | ||
|
|
d2f1656fdd | ||
|
|
5fbb1ab09d | ||
|
|
d0cc01877e | ||
|
|
a434628249 | ||
|
|
9cc616f720 | ||
|
|
4534bc06f5 | ||
|
|
798d30bbd9 | ||
|
|
7938aa2447 | ||
|
|
dda69389eb | ||
|
|
b20be10a19 | ||
|
|
0ee8fbabd5 | ||
|
|
1f562b25a7 | ||
|
|
6a2394052c | ||
|
|
593c0510d3 | ||
|
|
338e4ddc9f | ||
|
|
bfb1df3c40 | ||
|
|
003bf897e2 | ||
|
|
0b127956d3 | ||
|
|
098e560fcc | ||
|
|
7dbd3777ec | ||
|
|
447d8e5880 | ||
|
|
1f97225efa | ||
|
|
d13b0cfabb | ||
|
|
d7b852fca4 | ||
|
|
f2efe175e5 | ||
|
|
8f3a6638d8 | ||
|
|
f7471f56a4 | ||
|
|
edd8ba55d8 | ||
|
|
18aac84335 | ||
|
|
c6be892cb0 | ||
|
|
2cd8101987 | ||
|
|
e1aed37da0 | ||
|
|
5de5ecee06 | ||
|
|
9406901b28 | ||
|
|
477f478d85 | ||
|
|
668b5ad606 | ||
|
|
f985828f3b | ||
|
|
bb3bc940c2 | ||
|
|
2d5bc77219 | ||
|
|
a40df37192 | ||
|
|
63b3d25d78 | ||
|
|
74721b5c12 | ||
|
|
f136549b46 | ||
|
|
4ec2b2e311 | ||
|
|
3d82ee18c7 | ||
|
|
d6eae8c091 | ||
|
|
6f8d86cd8f | ||
|
|
3b6f226389 | ||
|
|
228e4e8e1a | ||
|
|
98a42feb95 | ||
|
|
2f93ee7591 | ||
|
|
11f5cb9a05 | ||
|
|
2c00fc31bc | ||
|
|
2bbf6b34ea | ||
|
|
8d7f282743 | ||
|
|
007da014f8 | ||
|
|
b26e50f777 | ||
|
|
611bc53c9a | ||
|
|
9d36582c10 | ||
|
|
1c735a9228 | ||
|
|
1db91fcec3 | ||
|
|
8b3b947406 | ||
|
|
2c0cadf2fa | ||
|
|
5e536556da | ||
|
|
d75029f54b | ||
|
|
204c4de1f6 | ||
|
|
0f3455a4a4 | ||
|
|
72f36e7237 | ||
|
|
d988daa025 | ||
|
|
e720504855 | ||
|
|
ee51c5ad9c | ||
|
|
4ac7df7364 | ||
|
|
56f873ccb3 | ||
|
|
1f90f846f3 | ||
|
|
4a97d5a8dc | ||
|
|
0eb9b6393d | ||
|
|
56d0ea46ea | ||
|
|
a7568eebdb | ||
|
|
4049e1944a | ||
|
|
73b7fcd907 | ||
|
|
74c1a97af4 | ||
|
|
97f2a53124 | ||
|
|
b6db872be0 | ||
|
|
0d9299f900 | ||
|
|
7f928dc684 | ||
|
|
231e138ab0 | ||
|
|
361dba58c6 | ||
|
|
e1b03b4a89 | ||
|
|
0df6c737c1 | ||
|
|
12c5aeaaa4 | ||
|
|
dd3fb17dd0 | ||
|
|
627a5d4355 | ||
|
|
58629bc1df | ||
|
|
f925803b93 | ||
|
|
843adf21f7 | ||
|
|
2d1b1e0592 | ||
|
|
38e9878c04 | ||
|
|
8cb8b95c2e | ||
|
|
8e4e308ccc | ||
|
|
f0f4049798 | ||
|
|
c20fe4ac17 | ||
|
|
e9c3312612 | ||
|
|
92ad895044 | ||
|
|
bcc2d9def3 | ||
|
|
43f61359da | ||
|
|
5e37ee4566 | ||
|
|
c544e0cce8 | ||
|
|
f119a3adec | ||
|
|
c951cb87a3 | ||
|
|
08147806a0 | ||
|
|
4beb11519e | ||
|
|
b7ebda4487 | ||
|
|
b4489301ac | ||
|
|
c025e5acc6 | ||
|
|
57745f36a8 | ||
|
|
eef1c99f11 | ||
|
|
9a19919392 | ||
|
|
3e2d62fe67 | ||
|
|
6f275eb63a | ||
|
|
b12dba4d15 | ||
|
|
4ee1b04523 | ||
|
|
b1decc9853 | ||
|
|
c2e4c033ef | ||
|
|
e12223df85 | ||
|
|
468922d5ed | ||
|
|
6b9a4b480b | ||
|
|
81b482e28b | ||
|
|
c112a84c0a | ||
|
|
88ab0b5e15 | ||
|
|
717cb75720 | ||
|
|
998938490c | ||
|
|
f3beca8769 | ||
|
|
4baeb6d922 | ||
|
|
98d860aff6 | ||
|
|
11a9e3991c | ||
|
|
f380d9dc25 | ||
|
|
d546ff154f | ||
|
|
f21597d332 | ||
|
|
d971c3a2ac | ||
|
|
80166a42bb | ||
|
|
3d8bdf1cf3 | ||
|
|
1ddce5aa8d | ||
|
|
7a1600fac4 | ||
|
|
e4e664d8ce | ||
|
|
145edd5a7d | ||
|
|
f5fed063ee | ||
|
|
a267395618 | ||
|
|
326b897b06 | ||
|
|
0b18366ab1 | ||
|
|
ddf599ba85 | ||
|
|
6e3e540d0a | ||
|
|
bd066f0cef | ||
|
|
9764f33086 | ||
|
|
0c19c878c5 | ||
|
|
1b8e517b5a | ||
|
|
2818a778a4 | ||
|
|
64a0264354 | ||
|
|
7932625644 | ||
|
|
4619fbbec3 | ||
|
|
6b64eb7650 | ||
|
|
f5a165d47d | ||
|
|
12c58e3955 | ||
|
|
5af0d17de4 | ||
|
|
81dfb8e3e5 | ||
|
|
d5114fc4bc | ||
|
|
693fc7fbbb | ||
|
|
b073b7e795 | ||
|
|
56d9719984 | ||
|
|
953c9723a8 | ||
|
|
c5a996d5ed | ||
|
|
53a83d823e | ||
|
|
6d75dcbc32 | ||
|
|
0345ee9c94 | ||
|
|
4016b5dc83 | ||
|
|
64b5e102aa | ||
|
|
8e3c44c072 | ||
|
|
12dc32f7e6 | ||
|
|
b4c38caf1e | ||
|
|
266b1a9913 | ||
|
|
1740d168c8 | ||
|
|
d42b397090 | ||
|
|
058cc1915b | ||
|
|
02d5bf85ae | ||
|
|
f0dac2454c | ||
|
|
d4deed0cf7 | ||
|
|
79655ffde5 | ||
|
|
cf46b45e8e | ||
|
|
ed3d21db77 | ||
|
|
f16e3593c0 | ||
|
|
67bb9340c7 | ||
|
|
5d49bd79f2 | ||
|
|
9f397b4337 | ||
|
|
7508d150d6 | ||
|
|
239db8168d | ||
|
|
30ab4386bf | ||
|
|
08053ccb15 | ||
|
|
367cfea8a7 | ||
|
|
5d3b7e3dab | ||
|
|
fe7e6e7b84 | ||
|
|
b2dba0d6fd | ||
|
|
6f290213fa | ||
|
|
0ab52d2f43 | ||
|
|
bf8a1062e0 | ||
|
|
0e254867b6 | ||
|
|
0376ac6908 | ||
|
|
b3421888a6 | ||
|
|
7b3f4ae0a4 | ||
|
|
b4e12cc922 | ||
|
|
6c282b18af | ||
|
|
ebbde8b7b6 | ||
|
|
a1407e4121 | ||
|
|
99b871b97a | ||
|
|
1cd3c4fcf4 | ||
|
|
e09ac9ee00 | ||
|
|
4b0d134acb | ||
|
|
eeec3979ee | ||
|
|
5b365c642d | ||
|
|
635201868a | ||
|
|
db4426e6b9 | ||
|
|
41902fee2e | ||
|
|
9239370793 | ||
|
|
a4d2f326a5 | ||
|
|
9f54ec26e2 | ||
|
|
9425cb56d7 | ||
|
|
1de56d2776 | ||
|
|
b3261ea930 | ||
|
|
88dd7aef72 | ||
|
|
2863605d84 | ||
|
|
94d9116299 | ||
|
|
57ddbbd515 | ||
|
|
78954b9d78 | ||
|
|
4eb06c9858 | ||
|
|
0d634c1dcc | ||
|
|
84f3740ea1 | ||
|
|
6dc48b6af7 | ||
|
|
09ce2816bf | ||
|
|
62e962eebe | ||
|
|
682472c1bd | ||
|
|
46ab70b839 | ||
|
|
ac8304f977 | ||
|
|
5777831565 | ||
|
|
42d1f41939 | ||
|
|
8c30ec3a3d | ||
|
|
237a1b648e | ||
|
|
614f1572c2 | ||
|
|
a48f16aa8c | ||
|
|
cdbadae002 | ||
|
|
4a28a39df6 | ||
|
|
5febf2542d | ||
|
|
c21ab11a41 | ||
|
|
10cd18dbf0 | ||
|
|
8409a13289 | ||
|
|
a9a73fa5c4 | ||
|
|
82cae2e11e | ||
|
|
42caee2418 | ||
|
|
1dea1d0d06 | ||
|
|
d344b9d878 | ||
|
|
95c1ce52cc | ||
|
|
cc346816d6 | ||
|
|
f14b561c33 | ||
|
|
6f655951aa | ||
|
|
ff8fbae568 | ||
|
|
4d4b02d076 | ||
|
|
06c0981ded | ||
|
|
20d581d536 | ||
|
|
45e110755d | ||
|
|
ab40532801 | ||
|
|
40f458a09c | ||
|
|
1ad233ca9d | ||
|
|
3a8e394272 | ||
|
|
1f54daa528 | ||
|
|
f25879b6fe | ||
|
|
8fa3109e91 | ||
|
|
808e8ff97a | ||
|
|
30685d4355 | ||
|
|
7152962026 | ||
|
|
91735e38d1 | ||
|
|
333a50ad9e | ||
|
|
b7a602fc67 | ||
|
|
2ff7ecef96 | ||
|
|
e3f9139304 | ||
|
|
4aa461872f | ||
|
|
3d43314076 | ||
|
|
7b1075b759 | ||
|
|
0c29e07ddb | ||
|
|
ce91cf22f9 | ||
|
|
2dd033c002 | ||
|
|
c7fcba112e | ||
|
|
c8b1c4358f | ||
|
|
5431e2e974 | ||
|
|
83e6082c56 | ||
|
|
c7bdbbde57 | ||
|
|
abf15c8aa8 | ||
|
|
d9db7e4a82 | ||
|
|
65dbc22ddd | ||
|
|
51961dd737 | ||
|
|
18a7055cdf | ||
|
|
4b9fddad6a | ||
|
|
fbe7bd7bf8 | ||
|
|
15edabdbb5 | ||
|
|
f447bcfb95 | ||
|
|
15e5e4fdf6 | ||
|
|
583c6b7249 | ||
|
|
18b933957e | ||
|
|
2c7039232e | ||
|
|
d3b3b5ff4a | ||
|
|
d90e8d1303 | ||
|
|
b55dd13dff | ||
|
|
66dd5b6f27 | ||
|
|
49c4b770eb | ||
|
|
662aaa1e75 | ||
|
|
dd4e47d7f9 | ||
|
|
9ea5073bc8 | ||
|
|
e314db8f56 | ||
|
|
48d936d068 | ||
|
|
b2ff8a15ef | ||
|
|
8a4d1cd7c6 | ||
|
|
8ce26c213d | ||
|
|
f3816b9abf | ||
|
|
21961780d4 | ||
|
|
305e2b61a0 | ||
|
|
0430f66240 | ||
|
|
65772edd00 | ||
|
|
02d7870d75 | ||
|
|
aca1709e13 | ||
|
|
b6ee0b014f | ||
|
|
e37186da73 | ||
|
|
588fa35c84 | ||
|
|
f6614cda66 | ||
|
|
639574d8c2 | ||
|
|
094703155c | ||
|
|
6dd254e713 | ||
|
|
204025721c | ||
|
|
27ffc1d225 | ||
|
|
ba6f0c39d5 | ||
|
|
ab2eac8f6c | ||
|
|
f460a0b30f | ||
|
|
50bc3ace06 | ||
|
|
d2ddf2002f | ||
|
|
b4117eeb02 | ||
|
|
106275b2dd | ||
|
|
08d9298be0 | ||
|
|
ff0c4d94fc | ||
|
|
50e50c0613 | ||
|
|
5c8a0e425b | ||
|
|
03b71caf7e | ||
|
|
7ff29d6086 | ||
|
|
8d86425875 | ||
|
|
97242d9726 | ||
|
|
780ff4e60b | ||
|
|
11743dfb5f | ||
|
|
9eaf85388c | ||
|
|
06635c9d2f | ||
|
|
1d2eef7894 | ||
|
|
85ed815ec2 | ||
|
|
096e5493a6 | ||
|
|
0aa8c03424 | ||
|
|
4ead3c34dd | ||
|
|
645034dde5 | ||
|
|
85706a3c57 | ||
|
|
c5ae4606b9 | ||
|
|
fa682215c5 | ||
|
|
e814733ae9 | ||
|
|
e2236698fa | ||
|
|
be5da632b3 | ||
|
|
dc73cd6dd9 | ||
|
|
7beb3bec75 | ||
|
|
53100b202d | ||
|
|
cc84b1f8bd | ||
|
|
474f52ed2b | ||
|
|
16225fc4c6 | ||
|
|
03bb7619da | ||
|
|
1bfb7451c3 | ||
|
|
3e082d5ed4 | ||
|
|
e45d67252c | ||
|
|
3d427c29c4 | ||
|
|
1068517b94 | ||
|
|
0d23ce1598 | ||
|
|
fd1ce20863 | ||
|
|
2c5fa63f40 | ||
|
|
78e43a37a5 | ||
|
|
fde85a9743 | ||
|
|
dbbc0adae5 | ||
|
|
2a62770552 | ||
|
|
f436b26e8e | ||
|
|
c566226747 | ||
|
|
cd405e038e | ||
|
|
92a37053b0 | ||
|
|
0b57cff27d | ||
|
|
3ebc44b546 | ||
|
|
68f1027ba7 | ||
|
|
005729be85 | ||
|
|
8bac4aa901 | ||
|
|
da170c7e51 | ||
|
|
211e69023e | ||
|
|
2912dcf010 | ||
|
|
3e00a3da06 | ||
|
|
a33e248828 | ||
|
|
75e14fbbed | ||
|
|
9922deac4d | ||
|
|
86be046c9f | ||
|
|
0f10bc3349 | ||
|
|
9685f0aef2 | ||
|
|
1e51000155 | ||
|
|
3bd459bb1a | ||
|
|
c89bc3c227 | ||
|
|
0f405a50aa | ||
|
|
f5e1643ef7 | ||
|
|
f62137fb58 | ||
|
|
37fbedd799 | ||
|
|
28b43f33fa | ||
|
|
81a72f29ea | ||
|
|
f7aaf4fb2a | ||
|
|
a52acf2ebd | ||
|
|
74c64619c3 | ||
|
|
4a5bc6450b | ||
|
|
fe69e7c6c4 | ||
|
|
ccf7c62aad | ||
|
|
f36cb8af63 | ||
|
|
10ccadd96c | ||
|
|
5c0e78bd53 | ||
|
|
8a09688117 | ||
|
|
a366bcf1a3 | ||
|
|
fcd4be9011 | ||
|
|
535eb76adc | ||
|
|
c6e68ac24f | ||
|
|
aff966aac9 | ||
|
|
32743b3aee | ||
|
|
a20ad87583 | ||
|
|
a11915db12 | ||
|
|
961f39a806 | ||
|
|
3096cb784c | ||
|
|
809aa4ff96 | ||
|
|
8d926d25ec | ||
|
|
790454f514 | ||
|
|
9a38707c58 | ||
|
|
fb7e2f7f7f | ||
|
|
f72efc80b2 | ||
|
|
fcda5399da | ||
|
|
fd3a9b00ec | ||
|
|
f56c37f9ee | ||
|
|
5f5000218a | ||
|
|
e8eb309d82 | ||
|
|
d0c3203e63 | ||
|
|
f5b3901caa | ||
|
|
1a99fea820 | ||
|
|
195b60615b | ||
|
|
2c394965b8 | ||
|
|
746d697691 | ||
|
|
5689158b43 | ||
|
|
6fcdf3d011 | ||
|
|
e26573c18e | ||
|
|
801cf8d9f0 | ||
|
|
eced8f2e93 | ||
|
|
3b735d07ec | ||
|
|
5eb5476e3a | ||
|
|
6a42a0054e | ||
|
|
8c437e19b8 | ||
|
|
9cd3b6c879 | ||
|
|
fe135acbec | ||
|
|
997c5bdcfa | ||
|
|
23e12c4539 | ||
|
|
ca9798be14 | ||
|
|
6e01a58c85 | ||
|
|
f618617053 | ||
|
|
49b8b9c372 | ||
|
|
129f975d96 | ||
|
|
a2e463e58c | ||
|
|
5fd50f0e15 | ||
|
|
7f9a915d71 | ||
|
|
0a81736b7a | ||
|
|
f9b6dd0c6a | ||
|
|
0354401b56 | ||
|
|
0304067beb | ||
|
|
ddd83da434 | ||
|
|
fc7df671de | ||
|
|
5fde9030c7 | ||
|
|
d7b07b3f00 | ||
|
|
ddd1ffb29f | ||
|
|
98094000bb | ||
|
|
d5026ef996 | ||
|
|
2cd913b9dd | ||
|
|
ad9520abbc | ||
|
|
c0fc57d10c | ||
|
|
0cf4d303e4 | ||
|
|
6de397958a | ||
|
|
55292a84dc | ||
|
|
981b560d53 | ||
|
|
c4c4dd55cd | ||
|
|
1ddbe20c86 | ||
|
|
da9e8c1550 | ||
|
|
ef0937fec4 | ||
|
|
35885b40de | ||
|
|
d669569196 | ||
|
|
ae919ff3c8 | ||
|
|
1a7a4690d1 | ||
|
|
b9b96d1a35 | ||
|
|
da3a9590ac | ||
|
|
6b3d75bea1 | ||
|
|
d44721fef0 | ||
|
|
3f268e8376 | ||
|
|
303fea4ebe | ||
|
|
77173cdad0 | ||
|
|
1e24a7d739 | ||
|
|
a3b33bedb8 | ||
|
|
eaf7544c50 | ||
|
|
67863120e0 | ||
|
|
1b0e305d9a | ||
|
|
91fda01071 |
2
.cocoapods.yml
Normal file
2
.cocoapods.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
try:
|
||||||
|
project: 'CoreStore.xcworkspace'
|
||||||
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: [JohnEstropia]
|
||||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -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
15
.jazzy.yaml
Normal 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
|
||||||
@@ -1 +0,0 @@
|
|||||||
3.1
|
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "self:CoreStoreDemo.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
@@ -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>
|
||||||
45
.travis.yml
45
.travis.yml
@@ -1,45 +0,0 @@
|
|||||||
language: objective-c
|
|
||||||
osx_image: xcode8.3
|
|
||||||
sudo: false
|
|
||||||
git:
|
|
||||||
submodules: false
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- LC_CTYPE=en_US.UTF-8
|
|
||||||
- LANG=en_US.UTF-8
|
|
||||||
matrix:
|
|
||||||
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
|
||||||
before_install:
|
|
||||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
|
||||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
|
||||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.20.1/Carthage.pkg"
|
|
||||||
- sudo installer -pkg "Carthage.pkg" -target /
|
|
||||||
- rm "Carthage.pkg"
|
|
||||||
before_script:
|
|
||||||
- carthage update --use-submodules
|
|
||||||
script:
|
|
||||||
- set -o pipefail
|
|
||||||
- xcodebuild -version
|
|
||||||
- xcodebuild -showsdks
|
|
||||||
- if [ $RUN_TESTS == "YES" ]; then
|
|
||||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
|
||||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
|
||||||
fi
|
|
||||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
|
||||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
|
||||||
- if [ $POD_LINT == "YES" ]; then
|
|
||||||
pod lib lint --quick;
|
|
||||||
fi
|
|
||||||
BIN
CoreStore.png
BIN
CoreStore.png
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 61 KiB |
@@ -1,20 +1,35 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "CoreStore"
|
s.name = "CoreStore"
|
||||||
s.version = "4.0.0-beta"
|
s.version = "9.3.0"
|
||||||
|
s.swift_version = "5.9"
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
|
||||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||||
|
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
|
||||||
|
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
||||||
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
|
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
|
||||||
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
|
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
|
||||||
|
|
||||||
s.ios.deployment_target = "8.0"
|
s.ios.deployment_target = "16.0"
|
||||||
s.osx.deployment_target = "10.10"
|
s.osx.deployment_target = "13.0"
|
||||||
s.watchos.deployment_target = "2.0"
|
s.tvos.deployment_target = "16.0"
|
||||||
s.tvos.deployment_target = "9.0"
|
s.watchos.deployment_target = "9.0"
|
||||||
|
|
||||||
s.source_files = "Sources", "Sources/**/*.{swift,h,m}"
|
s.source_files = "Sources", "Sources/**/*.swift"
|
||||||
s.public_header_files = "Sources/**/*.h"
|
s.public_header_files = "Sources/**/*.h"
|
||||||
s.frameworks = "Foundation", "CoreData"
|
s.frameworks = "Foundation", "CoreData"
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG' }
|
s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS[config=Debug]' => '-D DEBUG', 'OTHER_LDFLAGS' => '-weak_framework Combine -weak_framework SwiftUI' }
|
||||||
|
|
||||||
|
s.test_spec "CoreStoreTests" do |ts|
|
||||||
|
ts.source_files = "CoreStoreTests", "CoreStoreTests/**/*.swift", "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel"
|
||||||
|
ts.public_header_files = "CoreStoreTests/**/*.h"
|
||||||
|
ts.resources = [ "CoreStoreTests/**/*.xcdatamodeld", "CoreStoreTests/**/*.xcdatamodel" ]
|
||||||
|
ts.preserve_paths = "CoreStoreTests/**/*.xcdatamodeld"
|
||||||
|
ts.resource_bundles = { 'CoreStoreTests' => ["CoreStoreTests/**/*.momd"] }
|
||||||
|
ts.frameworks = "Foundation", "CoreData"
|
||||||
|
ts.requires_arc = true
|
||||||
|
ts.ios.deployment_target = "16.0"
|
||||||
|
ts.osx.deployment_target = "13.0"
|
||||||
|
ts.tvos.deployment_target = "16.0"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
BIN
CoreStore.sketch
BIN
CoreStore.sketch
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0800"
|
LastUpgradeVersion = "1600"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -27,6 +27,15 @@
|
|||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "B52DD1731BE1F8CC00949AFE"
|
||||||
|
BuildableName = "CoreStore.framework"
|
||||||
|
BlueprintName = "CoreStore OSX"
|
||||||
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
<Testables>
|
<Testables>
|
||||||
<TestableReference
|
<TestableReference
|
||||||
skipped = "NO">
|
skipped = "NO">
|
||||||
@@ -39,17 +48,6 @@
|
|||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "B52DD1731BE1F8CC00949AFE"
|
|
||||||
BuildableName = "CoreStore.framework"
|
|
||||||
BlueprintName = "CoreStore OSX"
|
|
||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -70,8 +68,6 @@
|
|||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0800"
|
LastUpgradeVersion = "1600"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -41,18 +41,6 @@
|
|||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "2F03A53A19C5C6DA005002A5"
|
|
||||||
BuildableName = "CoreStoreTests.xctest"
|
|
||||||
BlueprintName = "CoreStoreTests iOS"
|
|
||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
@@ -69,6 +57,18 @@
|
|||||||
isEnabled = "YES">
|
isEnabled = "YES">
|
||||||
</AdditionalOption>
|
</AdditionalOption>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "2F03A53A19C5C6DA005002A5"
|
||||||
|
BuildableName = "CoreStoreTests.xctest"
|
||||||
|
BlueprintName = "CoreStoreTests iOS"
|
||||||
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -89,8 +89,12 @@
|
|||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<CommandLineArguments>
|
||||||
</AdditionalOptions>
|
<CommandLineArgument
|
||||||
|
argument = "-com.apple.CoreData.SQLDebug 2"
|
||||||
|
isEnabled = "NO">
|
||||||
|
</CommandLineArgument>
|
||||||
|
</CommandLineArguments>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0800"
|
LastUpgradeVersion = "1600"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -27,6 +27,15 @@
|
|||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "82BA18881C4BBCBA00A0916E"
|
||||||
|
BuildableName = "CoreStore.framework"
|
||||||
|
BlueprintName = "CoreStore tvOS"
|
||||||
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
<Testables>
|
<Testables>
|
||||||
<TestableReference
|
<TestableReference
|
||||||
skipped = "NO">
|
skipped = "NO">
|
||||||
@@ -39,17 +48,6 @@
|
|||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "82BA18881C4BBCBA00A0916E"
|
|
||||||
BuildableName = "CoreStore.framework"
|
|
||||||
BlueprintName = "CoreStore tvOS"
|
|
||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -70,8 +68,6 @@
|
|||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "0800"
|
LastUpgradeVersion = "1600"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
@@ -20,6 +20,20 @@
|
|||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "NO"
|
||||||
|
buildForProfiling = "NO"
|
||||||
|
buildForArchiving = "NO"
|
||||||
|
buildForAnalyzing = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
|
||||||
|
BuildableName = "CoreStoreTests.xctest"
|
||||||
|
BlueprintName = "CoreStoreTests watchOS"
|
||||||
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
@@ -28,9 +42,17 @@
|
|||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
<Testables>
|
||||||
|
<TestableReference
|
||||||
|
skipped = "NO">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "B5114DA328CEEE5400EEAE78"
|
||||||
|
BuildableName = "CoreStoreTests.xctest"
|
||||||
|
BlueprintName = "CoreStoreTests watchOS"
|
||||||
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -51,8 +73,6 @@
|
|||||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|||||||
4
CoreStore.xcworkspace/contents.xcworkspacedata
generated
4
CoreStore.xcworkspace/contents.xcworkspacedata
generated
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -1,538 +0,0 @@
|
|||||||
// !$*UTF8*$!
|
|
||||||
{
|
|
||||||
archiveVersion = 1;
|
|
||||||
classes = {
|
|
||||||
};
|
|
||||||
objectVersion = 46;
|
|
||||||
objects = {
|
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
|
||||||
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */; };
|
|
||||||
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */; };
|
|
||||||
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
|
|
||||||
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
|
|
||||||
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; };
|
|
||||||
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
|
|
||||||
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
|
|
||||||
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
|
|
||||||
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977E01B120F8A003D50A5 /* CoreLocation.framework */; };
|
|
||||||
B52977E41B121635003D50A5 /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977E31B121635003D50A5 /* Place.swift */; };
|
|
||||||
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */; };
|
|
||||||
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */; };
|
|
||||||
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD571AF4D26E00848AE0 /* Main.storyboard */; };
|
|
||||||
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */; };
|
|
||||||
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */; };
|
|
||||||
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */; };
|
|
||||||
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */; };
|
|
||||||
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3311B11DF3200F4F0C6 /* UserAccount.swift */; };
|
|
||||||
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */; };
|
|
||||||
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */; };
|
|
||||||
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D91B231BCA0075EE4A /* MaleAccount.swift */; };
|
|
||||||
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */; };
|
|
||||||
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */; };
|
|
||||||
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965171B2E20CC0075EE4A /* TimeZone.swift */; };
|
|
||||||
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */; };
|
|
||||||
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */; };
|
|
||||||
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */; };
|
|
||||||
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */; };
|
|
||||||
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; };
|
|
||||||
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
|
||||||
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25841B36E23C0000406B /* OrganismV1.swift */; };
|
|
||||||
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25861B36E2520000406B /* OrganismV2.swift */; };
|
|
||||||
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */; };
|
|
||||||
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259A1B3EA4890000406B /* OrganismV3.swift */; };
|
|
||||||
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */; };
|
|
||||||
/* End PBXBuildFile section */
|
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
|
||||||
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */ = {
|
|
||||||
isa = PBXCopyFilesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
dstPath = "";
|
|
||||||
dstSubfolderSpec = 10;
|
|
||||||
files = (
|
|
||||||
B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */,
|
|
||||||
);
|
|
||||||
name = "Embed Frameworks";
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
|
||||||
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B503FADD1AFDC71700F90881 /* Palette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Palette.swift; sourceTree = "<group>"; };
|
|
||||||
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaletteTableViewCell.swift; sourceTree = "<group>"; };
|
|
||||||
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV2ToV3.xcmappingmodel; sourceTree = "<group>"; };
|
|
||||||
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV3ToV2.xcmappingmodel; sourceTree = "<group>"; };
|
|
||||||
B52977D81B120B80003D50A5 /* ObserversViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserversViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B52977DE1B120F83003D50A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
|
|
||||||
B52977E01B120F8A003D50A5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
|
|
||||||
B52977E31B121635003D50A5 /* Place.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = "<group>"; };
|
|
||||||
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CoreStoreDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
B54AAD4D1AF4D26E00848AE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
|
||||||
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
|
||||||
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CoreStoreDemo.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
B54AAD581AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
|
||||||
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
|
||||||
B54AAD5D1AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
|
||||||
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2ToV3MigrationPolicy.swift; sourceTree = "<group>"; };
|
|
||||||
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackSetupDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserAccount.swift; sourceTree = "<group>"; };
|
|
||||||
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomLoggerViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = StackSetupDemo.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
B56964D91B231BCA0075EE4A /* MaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaleAccount.swift; sourceTree = "<group>"; };
|
|
||||||
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FemaleAccount.swift; sourceTree = "<group>"; };
|
|
||||||
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingAndQueryingDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B56965171B2E20CC0075EE4A /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = "<group>"; };
|
|
||||||
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingResultsViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryingResultsViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemo.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
||||||
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OrganismTableViewCell.swift; path = "CoreStoreDemo/MIgrations Demo/OrganismTableViewCell.swift"; sourceTree = SOURCE_ROOT; };
|
|
||||||
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV2.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
B5EE25841B36E23C0000406B /* OrganismV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV1.swift; sourceTree = "<group>"; };
|
|
||||||
B5EE25861B36E2520000406B /* OrganismV2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2.swift; sourceTree = "<group>"; };
|
|
||||||
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV3.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationsDemoViewController.swift; sourceTree = "<group>"; };
|
|
||||||
B5EE259A1B3EA4890000406B /* OrganismV3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV3.swift; sourceTree = "<group>"; };
|
|
||||||
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismProtocol.swift; sourceTree = "<group>"; };
|
|
||||||
/* End PBXFileReference section */
|
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
|
||||||
B54AAD461AF4D26E00848AE0 /* Frameworks */ = {
|
|
||||||
isa = PBXFrameworksBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */,
|
|
||||||
B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */,
|
|
||||||
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXFrameworksBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
|
||||||
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B52977D81B120B80003D50A5 /* ObserversViewController.swift */,
|
|
||||||
B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */,
|
|
||||||
B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */,
|
|
||||||
B503FADD1AFDC71700F90881 /* Palette.swift */,
|
|
||||||
B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */,
|
|
||||||
);
|
|
||||||
path = "List and Object Observers Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B52977DB1B120F2C003D50A5 /* Transactions Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B52977E31B121635003D50A5 /* Place.swift */,
|
|
||||||
B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */,
|
|
||||||
);
|
|
||||||
path = "Transactions Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B52977E21B120F90003D50A5 /* Frameworks */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B52977E01B120F8A003D50A5 /* CoreLocation.framework */,
|
|
||||||
B5BDC9211C202429008147CD /* CoreStore.framework */,
|
|
||||||
B52977DE1B120F83003D50A5 /* MapKit.framework */,
|
|
||||||
);
|
|
||||||
name = Frameworks;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B54AAD401AF4D26E00848AE0 = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B52977E21B120F90003D50A5 /* Frameworks */,
|
|
||||||
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */,
|
|
||||||
B54AAD4A1AF4D26E00848AE0 /* Products */,
|
|
||||||
);
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B54AAD4A1AF4D26E00848AE0 /* Products */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */,
|
|
||||||
);
|
|
||||||
name = Products;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B54AAD4B1AF4D26E00848AE0 /* CoreStoreDemo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */,
|
|
||||||
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */,
|
|
||||||
B503FADA1AFDC71700F90881 /* List and Object Observers Demo */,
|
|
||||||
B52977DB1B120F2C003D50A5 /* Transactions Demo */,
|
|
||||||
B56965091B2B35370075EE4A /* Fetching and Querying Demo */,
|
|
||||||
B569652F1B3591460075EE4A /* Migrations Demo */,
|
|
||||||
B56964C61B20AC200075EE4A /* Loggers Demo */,
|
|
||||||
B54AAD571AF4D26E00848AE0 /* Main.storyboard */,
|
|
||||||
B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */,
|
|
||||||
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */,
|
|
||||||
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */,
|
|
||||||
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */,
|
|
||||||
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */,
|
|
||||||
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */,
|
|
||||||
);
|
|
||||||
path = CoreStoreDemo;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B54AAD4C1AF4D26E00848AE0 /* Supporting Files */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD4D1AF4D26E00848AE0 /* Info.plist */,
|
|
||||||
);
|
|
||||||
name = "Supporting Files";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B566E3271B117AE700F4F0C6 /* Stack Setup Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */,
|
|
||||||
B56964D91B231BCA0075EE4A /* MaleAccount.swift */,
|
|
||||||
B566E3311B11DF3200F4F0C6 /* UserAccount.swift */,
|
|
||||||
B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */,
|
|
||||||
);
|
|
||||||
path = "Stack Setup Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B56964C61B20AC200075EE4A /* Loggers Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */,
|
|
||||||
);
|
|
||||||
path = "Loggers Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B56965091B2B35370075EE4A /* Fetching and Querying Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B56965171B2E20CC0075EE4A /* TimeZone.swift */,
|
|
||||||
B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */,
|
|
||||||
B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */,
|
|
||||||
B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */,
|
|
||||||
);
|
|
||||||
path = "Fetching and Querying Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B569652F1B3591460075EE4A /* Migrations Demo */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */,
|
|
||||||
B5EE259A1B3EA4890000406B /* OrganismV3.swift */,
|
|
||||||
B5EE25861B36E2520000406B /* OrganismV2.swift */,
|
|
||||||
B5EE25841B36E23C0000406B /* OrganismV1.swift */,
|
|
||||||
B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */,
|
|
||||||
B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */,
|
|
||||||
B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */,
|
|
||||||
B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */,
|
|
||||||
B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */,
|
|
||||||
);
|
|
||||||
path = "Migrations Demo";
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXGroup section */
|
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
|
||||||
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */ = {
|
|
||||||
isa = PBXNativeTarget;
|
|
||||||
buildConfigurationList = B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */;
|
|
||||||
buildPhases = (
|
|
||||||
B54AAD451AF4D26E00848AE0 /* Sources */,
|
|
||||||
B54AAD461AF4D26E00848AE0 /* Frameworks */,
|
|
||||||
B54AAD471AF4D26E00848AE0 /* Resources */,
|
|
||||||
B5E89ACF1C52929C003B04A9 /* Embed Frameworks */,
|
|
||||||
);
|
|
||||||
buildRules = (
|
|
||||||
);
|
|
||||||
dependencies = (
|
|
||||||
);
|
|
||||||
name = CoreStoreDemo;
|
|
||||||
productName = CoreStoreDemo;
|
|
||||||
productReference = B54AAD491AF4D26E00848AE0 /* CoreStoreDemo.app */;
|
|
||||||
productType = "com.apple.product-type.application";
|
|
||||||
};
|
|
||||||
/* End PBXNativeTarget section */
|
|
||||||
|
|
||||||
/* Begin PBXProject section */
|
|
||||||
B54AAD411AF4D26E00848AE0 /* Project object */ = {
|
|
||||||
isa = PBXProject;
|
|
||||||
attributes = {
|
|
||||||
LastSwiftUpdateCheck = 0700;
|
|
||||||
LastUpgradeCheck = 0800;
|
|
||||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
|
||||||
TargetAttributes = {
|
|
||||||
B54AAD481AF4D26E00848AE0 = {
|
|
||||||
CreatedOnToolsVersion = 6.3;
|
|
||||||
LastSwiftMigration = 0800;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */;
|
|
||||||
compatibilityVersion = "Xcode 3.2";
|
|
||||||
developmentRegion = English;
|
|
||||||
hasScannedForEncodings = 0;
|
|
||||||
knownRegions = (
|
|
||||||
en,
|
|
||||||
Base,
|
|
||||||
);
|
|
||||||
mainGroup = B54AAD401AF4D26E00848AE0;
|
|
||||||
productRefGroup = B54AAD4A1AF4D26E00848AE0 /* Products */;
|
|
||||||
projectDirPath = "";
|
|
||||||
projectRoot = "";
|
|
||||||
targets = (
|
|
||||||
B54AAD481AF4D26E00848AE0 /* CoreStoreDemo */,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
/* End PBXProject section */
|
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
|
||||||
B54AAD471AF4D26E00848AE0 /* Resources */ = {
|
|
||||||
isa = PBXResourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */,
|
|
||||||
B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */,
|
|
||||||
B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXResourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
|
||||||
B54AAD451AF4D26E00848AE0 /* Sources */ = {
|
|
||||||
isa = PBXSourcesBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */,
|
|
||||||
B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */,
|
|
||||||
B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */,
|
|
||||||
B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */,
|
|
||||||
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */,
|
|
||||||
B52977E41B121635003D50A5 /* Place.swift in Sources */,
|
|
||||||
B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */,
|
|
||||||
B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */,
|
|
||||||
B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */,
|
|
||||||
B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */,
|
|
||||||
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */,
|
|
||||||
B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */,
|
|
||||||
B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */,
|
|
||||||
B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */,
|
|
||||||
B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */,
|
|
||||||
B54AAD521AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld in Sources */,
|
|
||||||
B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */,
|
|
||||||
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
|
|
||||||
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
|
|
||||||
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
|
|
||||||
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
|
|
||||||
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
|
|
||||||
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */,
|
|
||||||
B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */,
|
|
||||||
B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */,
|
|
||||||
B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */,
|
|
||||||
B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */,
|
|
||||||
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */,
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
};
|
|
||||||
/* End PBXSourcesBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
|
||||||
B54AAD571AF4D26E00848AE0 /* Main.storyboard */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD581AF4D26E00848AE0 /* Base */,
|
|
||||||
);
|
|
||||||
name = Main.storyboard;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */ = {
|
|
||||||
isa = PBXVariantGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD5D1AF4D26E00848AE0 /* Base */,
|
|
||||||
);
|
|
||||||
name = LaunchScreen.xib;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
/* End PBXVariantGroup section */
|
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
|
||||||
B54AAD6B1AF4D26E00848AE0 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
ENABLE_TESTABILITY = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
||||||
"DEBUG=1",
|
|
||||||
"$(inherited)",
|
|
||||||
);
|
|
||||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
B54AAD6C1AF4D26E00848AE0 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
|
||||||
CLANG_ENABLE_MODULES = YES;
|
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
|
||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
|
||||||
COPY_PHASE_STRIP = NO;
|
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
|
||||||
SDKROOT = iphoneos;
|
|
||||||
VALIDATE_PRODUCT = YES;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
B54AAD6E1AF4D26E00848AE0 /* Debug */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
};
|
|
||||||
name = Debug;
|
|
||||||
};
|
|
||||||
B54AAD6F1AF4D26E00848AE0 /* Release */ = {
|
|
||||||
isa = XCBuildConfiguration;
|
|
||||||
buildSettings = {
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
||||||
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
|
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
|
||||||
SWIFT_VERSION = 3.0;
|
|
||||||
};
|
|
||||||
name = Release;
|
|
||||||
};
|
|
||||||
/* End XCBuildConfiguration section */
|
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
|
||||||
B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
B54AAD6B1AF4D26E00848AE0 /* Debug */,
|
|
||||||
B54AAD6C1AF4D26E00848AE0 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "CoreStoreDemo" */ = {
|
|
||||||
isa = XCConfigurationList;
|
|
||||||
buildConfigurations = (
|
|
||||||
B54AAD6E1AF4D26E00848AE0 /* Debug */,
|
|
||||||
B54AAD6F1AF4D26E00848AE0 /* Release */,
|
|
||||||
);
|
|
||||||
defaultConfigurationIsVisible = 0;
|
|
||||||
defaultConfigurationName = Release;
|
|
||||||
};
|
|
||||||
/* End XCConfigurationList section */
|
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
|
||||||
B54AAD501AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodeld */ = {
|
|
||||||
isa = XCVersionGroup;
|
|
||||||
children = (
|
|
||||||
B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */,
|
|
||||||
);
|
|
||||||
currentVersion = B54AAD511AF4D26E00848AE0 /* CoreStoreDemo.xcdatamodel */;
|
|
||||||
path = CoreStoreDemo.xcdatamodeld;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
|
||||||
};
|
|
||||||
B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */ = {
|
|
||||||
isa = XCVersionGroup;
|
|
||||||
children = (
|
|
||||||
B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */,
|
|
||||||
);
|
|
||||||
currentVersion = B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */;
|
|
||||||
path = StackSetupDemo.xcdatamodeld;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
|
||||||
};
|
|
||||||
B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */ = {
|
|
||||||
isa = XCVersionGroup;
|
|
||||||
children = (
|
|
||||||
B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */,
|
|
||||||
B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */,
|
|
||||||
B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */,
|
|
||||||
);
|
|
||||||
currentVersion = B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */;
|
|
||||||
path = MigrationDemo.xcdatamodeld;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
|
||||||
};
|
|
||||||
/* End XCVersionGroup section */
|
|
||||||
};
|
|
||||||
rootObject = B54AAD411AF4D26E00848AE0 /* Project object */;
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
//
|
|
||||||
// AppDelegate.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/02.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
// MARK: - AppDelegate
|
|
||||||
|
|
||||||
@UIApplicationMain
|
|
||||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
||||||
|
|
||||||
// MARK: UIApplicationDelegate
|
|
||||||
|
|
||||||
var window: UIWindow?
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
|
|
||||||
|
|
||||||
application.statusBarStyle = .lightContent
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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>
|
|
||||||
@@ -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
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="10169.1" systemVersion="15D21" minimumToolsVersion="Automatic">
|
|
||||||
<entity name="Palette" representedClassName="CoreStoreDemo.Palette">
|
|
||||||
<attribute name="brightness" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<attribute name="colorName" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
|
|
||||||
<attribute name="hue" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<userInfo/>
|
|
||||||
</entity>
|
|
||||||
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
|
|
||||||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
|
|
||||||
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
|
|
||||||
</entity>
|
|
||||||
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
|
|
||||||
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
|
|
||||||
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" syncable="YES"/>
|
|
||||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
|
||||||
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
|
||||||
</entity>
|
|
||||||
<configuration name="FetchingAndQueryingDemo">
|
|
||||||
<memberEntity name="TimeZone"/>
|
|
||||||
</configuration>
|
|
||||||
<configuration name="ObservingDemo">
|
|
||||||
<memberEntity name="Palette"/>
|
|
||||||
</configuration>
|
|
||||||
<configuration name="TransactionsDemo">
|
|
||||||
<memberEntity name="Place"/>
|
|
||||||
</configuration>
|
|
||||||
<elements>
|
|
||||||
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
|
|
||||||
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
|
|
||||||
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
|
|
||||||
</elements>
|
|
||||||
</model>
|
|
||||||
@@ -1,291 +0,0 @@
|
|||||||
//
|
|
||||||
// FetchingAndQueryingDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/06/12.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
private struct Static {
|
|
||||||
|
|
||||||
static let timeZonesStack: DataStack = {
|
|
||||||
|
|
||||||
let dataStack = DataStack()
|
|
||||||
try! dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "TimeZoneDemo.sqlite",
|
|
||||||
configuration: "FetchingAndQueryingDemo",
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
_ = try? dataStack.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
transaction.deleteAll(From<TimeZone>())
|
|
||||||
|
|
||||||
for name in NSTimeZone.knownTimeZoneNames {
|
|
||||||
|
|
||||||
let rawTimeZone = NSTimeZone(name: name)!
|
|
||||||
let cachedTimeZone = transaction.create(Into<TimeZone>())
|
|
||||||
|
|
||||||
cachedTimeZone.name = rawTimeZone.name
|
|
||||||
cachedTimeZone.abbreviation = rawTimeZone.abbreviation ?? ""
|
|
||||||
cachedTimeZone.secondsFromGMT = Int32(rawTimeZone.secondsFromGMT)
|
|
||||||
cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime
|
|
||||||
cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return dataStack
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - FetchingAndQueryingDemoViewController
|
|
||||||
|
|
||||||
class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
if self.didAppearOnce {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.didAppearOnce = true
|
|
||||||
|
|
||||||
let alert = UIAlertController(
|
|
||||||
title: "Fetch and Query Demo",
|
|
||||||
message: "This demo shows how to execute fetches and queries.\n\nEach menu item executes and displays a preconfigured fetch/query.",
|
|
||||||
preferredStyle: .alert
|
|
||||||
)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
||||||
|
|
||||||
super.prepare(for: segue, sender: sender)
|
|
||||||
|
|
||||||
if let indexPath = sender as? IndexPath {
|
|
||||||
|
|
||||||
switch segue.destination {
|
|
||||||
|
|
||||||
case let controller as FetchingResultsViewController:
|
|
||||||
let item = self.fetchingItems[indexPath.row]
|
|
||||||
controller.set(timeZones: item.fetch(), title: item.title)
|
|
||||||
|
|
||||||
case let controller as QueryingResultsViewController:
|
|
||||||
let item = self.queryingItems[indexPath.row]
|
|
||||||
controller.set(value: item.query(), title: item.title)
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDataSource
|
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
|
|
||||||
switch self.segmentedControl?.selectedSegmentIndex {
|
|
||||||
|
|
||||||
case Section.fetching.rawValue?:
|
|
||||||
return self.fetchingItems.count
|
|
||||||
|
|
||||||
case Section.querying.rawValue?:
|
|
||||||
return self.queryingItems.count
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
|
|
||||||
|
|
||||||
switch self.segmentedControl?.selectedSegmentIndex {
|
|
||||||
|
|
||||||
case Section.fetching.rawValue?:
|
|
||||||
cell.textLabel?.text = self.fetchingItems[indexPath.row].title
|
|
||||||
|
|
||||||
case Section.querying.rawValue?:
|
|
||||||
cell.textLabel?.text = self.queryingItems[indexPath.row].title
|
|
||||||
|
|
||||||
default:
|
|
||||||
cell.textLabel?.text = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDelegate
|
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
|
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
|
||||||
|
|
||||||
switch self.segmentedControl?.selectedSegmentIndex {
|
|
||||||
|
|
||||||
case Section.fetching.rawValue?:
|
|
||||||
self.performSegue(withIdentifier: "FetchingResultsViewController", sender: indexPath)
|
|
||||||
|
|
||||||
case Section.querying.rawValue?:
|
|
||||||
self.performSegue(withIdentifier: "QueryingResultsViewController", sender: indexPath)
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
private enum Section: Int {
|
|
||||||
|
|
||||||
case fetching
|
|
||||||
case querying
|
|
||||||
}
|
|
||||||
|
|
||||||
private let fetchingItems = [
|
|
||||||
(
|
|
||||||
title: "All Time Zones",
|
|
||||||
fetch: { () -> [TimeZone] in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.fetchAll(
|
|
||||||
From<TimeZone>(),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Time Zones in Asia",
|
|
||||||
fetch: { () -> [TimeZone] in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.fetchAll(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Asia"),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Time Zones in America and Europe",
|
|
||||||
fetch: { () -> [TimeZone] in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.fetchAll(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America")
|
|
||||||
|| Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Europe"),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "All Time Zones Except America",
|
|
||||||
fetch: { () -> [TimeZone] in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.fetchAll(
|
|
||||||
From<TimeZone>(),
|
|
||||||
!Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America"),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Time Zones with Summer Time",
|
|
||||||
fetch: { () -> [TimeZone] in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.fetchAll(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Where("hasDaylightSavingTime", isEqualTo: true),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
private let queryingItems = [
|
|
||||||
(
|
|
||||||
title: "Number of Time Zones",
|
|
||||||
query: { () -> Any in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.queryValue(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Select<NSNumber>(.count(#keyPath(TimeZone.name)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Abbreviation For Tokyo's Time Zone",
|
|
||||||
query: { () -> Any in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.queryValue(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Select<String>(#keyPath(TimeZone.abbreviation)),
|
|
||||||
Where("%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "All Abbreviations",
|
|
||||||
query: { () -> Any in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.queryAttributes(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Select<NSDictionary>(#keyPath(TimeZone.name), #keyPath(TimeZone.abbreviation)),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Number of Countries per Time Zone",
|
|
||||||
query: { () -> Any in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.queryAttributes(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Select<NSDictionary>(.count(#keyPath(TimeZone.abbreviation)), #keyPath(TimeZone.abbreviation)),
|
|
||||||
GroupBy(#keyPath(TimeZone.abbreviation)),
|
|
||||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)), .ascending(#keyPath(TimeZone.name)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
title: "Number of Countries with Summer Time",
|
|
||||||
query: { () -> Any in
|
|
||||||
|
|
||||||
return Static.timeZonesStack.queryAttributes(
|
|
||||||
From<TimeZone>(),
|
|
||||||
Select<NSDictionary>(
|
|
||||||
.count(#keyPath(TimeZone.hasDaylightSavingTime), as: "numberOfCountries"),
|
|
||||||
#keyPath(TimeZone.hasDaylightSavingTime)
|
|
||||||
),
|
|
||||||
GroupBy(#keyPath(TimeZone.hasDaylightSavingTime)),
|
|
||||||
OrderBy(.descending(#keyPath(TimeZone.hasDaylightSavingTime)))
|
|
||||||
)!
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
var didAppearOnce = false
|
|
||||||
|
|
||||||
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
|
|
||||||
@IBOutlet dynamic weak var tableView: UITableView?
|
|
||||||
|
|
||||||
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
self.tableView?.reloadData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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?
|
|
||||||
}
|
|
||||||
@@ -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?
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 |
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "first.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"images" : [
|
|
||||||
{
|
|
||||||
"idiom" : "universal",
|
|
||||||
"filename" : "second.pdf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"info" : {
|
|
||||||
"version" : 1,
|
|
||||||
"author" : "xcode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,315 +0,0 @@
|
|||||||
//
|
|
||||||
// ListObserverDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/02.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
private struct Static {
|
|
||||||
|
|
||||||
enum Filter: String {
|
|
||||||
|
|
||||||
case all = "All Colors"
|
|
||||||
case light = "Light Colors"
|
|
||||||
case dark = "Dark Colors"
|
|
||||||
|
|
||||||
func next() -> Filter {
|
|
||||||
|
|
||||||
switch self {
|
|
||||||
|
|
||||||
case .all: return .light
|
|
||||||
case .light: return .dark
|
|
||||||
case .dark: return .all
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func whereClause() -> Where {
|
|
||||||
|
|
||||||
switch self {
|
|
||||||
|
|
||||||
case .all: return Where(true)
|
|
||||||
case .light: return Where("%K >= %@", #keyPath(Palette.brightness), 0.9)
|
|
||||||
case .dark: return Where("%K <= %@", #keyPath(Palette.brightness), 0.4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static var filter = Filter.all {
|
|
||||||
|
|
||||||
didSet {
|
|
||||||
|
|
||||||
self.palettes.refetch(
|
|
||||||
self.filter.whereClause(),
|
|
||||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static let palettes: ListMonitor<Palette> = {
|
|
||||||
|
|
||||||
try! CoreStore.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "ColorsDemo.sqlite",
|
|
||||||
configuration: "ObservingDemo",
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return CoreStore.monitorSectionedList(
|
|
||||||
From<Palette>(),
|
|
||||||
SectionBy(#keyPath(Palette.colorName)),
|
|
||||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
|
||||||
)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - ListObserverDemoViewController
|
|
||||||
|
|
||||||
class ListObserverDemoViewController: UITableViewController, ListSectionObserver {
|
|
||||||
|
|
||||||
// MARK: NSObject
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
|
|
||||||
Static.palettes.removeObserver(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
let navigationItem = self.navigationItem
|
|
||||||
navigationItem.leftBarButtonItems = [
|
|
||||||
self.editButtonItem,
|
|
||||||
UIBarButtonItem(
|
|
||||||
barButtonSystemItem: .trash,
|
|
||||||
target: self,
|
|
||||||
action: #selector(self.resetBarButtonItemTouched(_:))
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
let filterBarButton = UIBarButtonItem(
|
|
||||||
title: Static.filter.rawValue,
|
|
||||||
style: .plain,
|
|
||||||
target: self,
|
|
||||||
action: #selector(self.filterBarButtonItemTouched(_:))
|
|
||||||
)
|
|
||||||
navigationItem.rightBarButtonItems = [
|
|
||||||
UIBarButtonItem(
|
|
||||||
barButtonSystemItem: .add,
|
|
||||||
target: self,
|
|
||||||
action: #selector(self.addBarButtonItemTouched(_:))
|
|
||||||
),
|
|
||||||
filterBarButton
|
|
||||||
]
|
|
||||||
self.filterBarButton = filterBarButton
|
|
||||||
|
|
||||||
Static.palettes.addObserver(self)
|
|
||||||
|
|
||||||
self.setTable(enabled: !Static.palettes.isPendingRefetch)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
||||||
|
|
||||||
super.prepare(for: segue, sender: sender)
|
|
||||||
|
|
||||||
switch (segue.identifier, segue.destination, sender) {
|
|
||||||
|
|
||||||
case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as Palette):
|
|
||||||
destinationViewController.palette = palette
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDataSource
|
|
||||||
|
|
||||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
||||||
|
|
||||||
return Static.palettes.numberOfSections()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
|
|
||||||
return Static.palettes.numberOfObjectsInSection(section)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
|
|
||||||
|
|
||||||
let palette = Static.palettes[indexPath]
|
|
||||||
cell.colorView?.backgroundColor = palette.color
|
|
||||||
cell.label?.text = palette.colorText
|
|
||||||
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDelegate
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
|
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
|
||||||
|
|
||||||
self.performSegue(
|
|
||||||
withIdentifier: "ObjectObserverDemoViewController",
|
|
||||||
sender: Static.palettes[indexPath]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
|
|
||||||
|
|
||||||
switch editingStyle {
|
|
||||||
|
|
||||||
case .delete:
|
|
||||||
let palette = Static.palettes[indexPath]
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
transaction.delete(palette)
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
||||||
|
|
||||||
return Static.palettes.sectionInfoAtIndex(section).name
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: ListObserver
|
|
||||||
|
|
||||||
func listMonitorWillChange(_ monitor: ListMonitor<Palette>) {
|
|
||||||
|
|
||||||
self.tableView.beginUpdates()
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitorDidChange(_ monitor: ListMonitor<Palette>) {
|
|
||||||
|
|
||||||
self.tableView.endUpdates()
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitorWillRefetch(_ monitor: ListMonitor<Palette>) {
|
|
||||||
|
|
||||||
self.setTable(enabled: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitorDidRefetch(_ monitor: ListMonitor<Palette>) {
|
|
||||||
|
|
||||||
self.filterBarButton?.title = Static.filter.rawValue
|
|
||||||
self.tableView.reloadData()
|
|
||||||
self.setTable(enabled: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: ListObjectObserver
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didInsertObject object: Palette, toIndexPath indexPath: IndexPath) {
|
|
||||||
|
|
||||||
self.tableView.insertRows(at: [indexPath], with: .automatic)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteObject object: Palette, fromIndexPath indexPath: IndexPath) {
|
|
||||||
|
|
||||||
self.tableView.deleteRows(at: [indexPath], with: .automatic)
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didUpdateObject object: Palette, atIndexPath indexPath: IndexPath) {
|
|
||||||
|
|
||||||
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
|
|
||||||
|
|
||||||
let palette = Static.palettes[indexPath]
|
|
||||||
cell.colorView?.backgroundColor = palette.color
|
|
||||||
cell.label?.text = palette.colorText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didMoveObject object: Palette, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
|
|
||||||
|
|
||||||
self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
|
|
||||||
self.tableView.insertRows(at: [toIndexPath], with: .automatic)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: ListSectionObserver
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) {
|
|
||||||
|
|
||||||
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
|
|
||||||
|
|
||||||
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
private var filterBarButton: UIBarButtonItem?
|
|
||||||
|
|
||||||
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
transaction.deleteAll(From<Palette>())
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
Static.filter = Static.filter.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
let palette = transaction.create(Into<Palette>())
|
|
||||||
palette.setInitialValues()
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setTable(enabled: Bool) {
|
|
||||||
|
|
||||||
UIView.animate(
|
|
||||||
withDuration: 0.2,
|
|
||||||
delay: 0,
|
|
||||||
options: .beginFromCurrentState,
|
|
||||||
animations: { () -> Void in
|
|
||||||
|
|
||||||
if let tableView = self.tableView {
|
|
||||||
|
|
||||||
tableView.alpha = enabled ? 1.0 : 0.5
|
|
||||||
tableView.isUserInteractionEnabled = enabled
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: nil
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
//
|
|
||||||
// ObjectObserverDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/06.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - ObjectObserverDemoViewController
|
|
||||||
|
|
||||||
class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
|
||||||
|
|
||||||
var palette: Palette? {
|
|
||||||
|
|
||||||
get {
|
|
||||||
|
|
||||||
return self.monitor?.object
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
|
|
||||||
guard self.monitor?.object != newValue else {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let palette = newValue {
|
|
||||||
|
|
||||||
self.monitor = CoreStore.monitorObject(palette)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
self.monitor = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: NSObject
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
|
|
||||||
self.monitor?.removeObserver(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
|
||||||
|
|
||||||
if let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue)))) {
|
|
||||||
|
|
||||||
self.monitor = CoreStore.monitorObject(palette)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
_ = try? CoreStore.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
let palette = transaction.create(Into(Palette.self))
|
|
||||||
palette.setInitialValues()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
|
|
||||||
self.monitor = CoreStore.monitorObject(palette)
|
|
||||||
}
|
|
||||||
|
|
||||||
super.init(coder: aDecoder)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
|
|
||||||
super.viewDidLoad()
|
|
||||||
self.monitor?.addObserver(self)
|
|
||||||
|
|
||||||
if let palette = self.monitor?.object {
|
|
||||||
|
|
||||||
self.reloadPaletteInfo(palette, changedKeys: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: ObjectObserver
|
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPath>) {
|
|
||||||
|
|
||||||
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didDeleteObject object: Palette) {
|
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem?.isEnabled = false
|
|
||||||
|
|
||||||
self.colorNameLabel?.alpha = 0.3
|
|
||||||
self.colorView?.alpha = 0.3
|
|
||||||
|
|
||||||
self.hsbLabel?.text = "Deleted"
|
|
||||||
self.hsbLabel?.textColor = UIColor.red
|
|
||||||
|
|
||||||
self.hueSlider?.isEnabled = false
|
|
||||||
self.saturationSlider?.isEnabled = false
|
|
||||||
self.brightnessSlider?.isEnabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
var monitor: ObjectMonitor<Palette>?
|
|
||||||
|
|
||||||
@IBOutlet weak var colorNameLabel: UILabel?
|
|
||||||
@IBOutlet weak var colorView: UIView?
|
|
||||||
@IBOutlet weak var hsbLabel: UILabel?
|
|
||||||
@IBOutlet weak var dateLabel: UILabel?
|
|
||||||
@IBOutlet weak var hueSlider: UISlider?
|
|
||||||
@IBOutlet weak var saturationSlider: UISlider?
|
|
||||||
@IBOutlet weak var brightnessSlider: UISlider?
|
|
||||||
|
|
||||||
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
let hue = self.hueSlider?.value ?? 0
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { [weak self] (transaction) in
|
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
|
||||||
|
|
||||||
palette.hue = Int32(hue)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
let saturation = self.saturationSlider?.value ?? 0
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { [weak self] (transaction) in
|
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
|
||||||
|
|
||||||
palette.saturation = saturation
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
let brightness = self.brightnessSlider?.value ?? 0
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { [weak self] (transaction) in
|
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
|
||||||
|
|
||||||
palette.brightness = brightness
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { [weak self] (transaction) in
|
|
||||||
|
|
||||||
transaction.delete(self?.monitor?.object)
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
|
|
||||||
|
|
||||||
self.colorNameLabel?.text = palette.colorName
|
|
||||||
|
|
||||||
let color = palette.color
|
|
||||||
self.colorNameLabel?.textColor = color
|
|
||||||
self.colorView?.backgroundColor = color
|
|
||||||
|
|
||||||
self.hsbLabel?.text = palette.colorText
|
|
||||||
|
|
||||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.hue)) == true {
|
|
||||||
|
|
||||||
self.hueSlider?.value = Float(palette.hue)
|
|
||||||
}
|
|
||||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.saturation)) == true {
|
|
||||||
|
|
||||||
self.saturationSlider?.value = palette.saturation
|
|
||||||
}
|
|
||||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.brightness)) == true {
|
|
||||||
|
|
||||||
self.brightnessSlider?.value = palette.brightness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
//
|
|
||||||
// Palette.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/05.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
import CoreData
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Palette
|
|
||||||
|
|
||||||
class Palette: NSManagedObject {
|
|
||||||
|
|
||||||
@NSManaged var hue: Int32
|
|
||||||
@NSManaged var saturation: Float
|
|
||||||
@NSManaged var brightness: Float
|
|
||||||
|
|
||||||
@objc dynamic var colorName: String {
|
|
||||||
|
|
||||||
get {
|
|
||||||
|
|
||||||
let KVCKey = #keyPath(Palette.colorName)
|
|
||||||
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
|
|
||||||
|
|
||||||
return colorName
|
|
||||||
}
|
|
||||||
|
|
||||||
let colorName: String
|
|
||||||
switch self.hue % 360 {
|
|
||||||
|
|
||||||
case 0 ..< 20: colorName = "Lower Reds"
|
|
||||||
case 20 ..< 57: colorName = "Oranges and Browns"
|
|
||||||
case 57 ..< 90: colorName = "Yellow-Greens"
|
|
||||||
case 90 ..< 159: colorName = "Greens"
|
|
||||||
case 159 ..< 197: colorName = "Blue-Greens"
|
|
||||||
case 197 ..< 241: colorName = "Blues"
|
|
||||||
case 241 ..< 297: colorName = "Violets"
|
|
||||||
case 297 ..< 331: colorName = "Magentas"
|
|
||||||
default: colorName = "Upper Reds"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.setPrimitiveValue(colorName, forKey: KVCKey)
|
|
||||||
return colorName
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
|
|
||||||
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var color: UIColor {
|
|
||||||
|
|
||||||
return UIColor(
|
|
||||||
hue: CGFloat(self.hue) / 360.0,
|
|
||||||
saturation: CGFloat(self.saturation),
|
|
||||||
brightness: CGFloat(self.brightness),
|
|
||||||
alpha: 1.0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorText: String {
|
|
||||||
|
|
||||||
return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%"
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInitialValues() {
|
|
||||||
|
|
||||||
self.hue = Int32(arc4random_uniform(360))
|
|
||||||
self.saturation = 1.0
|
|
||||||
self.brightness = Float(arc4random_uniform(70) + 30) / 100.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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?
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
//
|
|
||||||
// CustomLoggerViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/06/05.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - CustomLoggerViewController
|
|
||||||
|
|
||||||
class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
|
||||||
|
|
||||||
// MARK: NSObject
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
|
|
||||||
CoreStore.logger = DefaultLogger()
|
|
||||||
}
|
|
||||||
|
|
||||||
let dataStack = DataStack()
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
try! self.dataStack.addStorageAndWait(SQLiteStore(fileName: "emptyStore.sqlite"))
|
|
||||||
CoreStore.logger = self
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
let alert = UIAlertController(
|
|
||||||
title: "Logger Demo",
|
|
||||||
message: "This demo shows how to plug-in any logging framework to CoreStore.\n\nThe view controller implements CoreStoreLogger and appends all logs to the text view.",
|
|
||||||
preferredStyle: .alert
|
|
||||||
)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: CoreStoreLogger
|
|
||||||
|
|
||||||
func log(level: LogLevel, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
|
|
||||||
let levelString: String
|
|
||||||
switch level {
|
|
||||||
|
|
||||||
case .trace: levelString = "Trace"
|
|
||||||
case .notice: levelString = "Notice"
|
|
||||||
case .warning: levelString = "Warning"
|
|
||||||
case .fatal: levelString = "Fatal"
|
|
||||||
}
|
|
||||||
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log:\(levelString)] \(message)\n\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func log(error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
|
|
||||||
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Error] \(message): \(error)\n\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func assert(_ condition: @autoclosure () -> Bool, message: @autoclosure () -> String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
|
||||||
|
|
||||||
if condition() {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let messageString = message()
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
|
|
||||||
self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Assert] \(messageString)\n\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
@IBOutlet dynamic weak var textView: UITextView?
|
|
||||||
@IBOutlet dynamic weak var segmentedControl: UISegmentedControl?
|
|
||||||
|
|
||||||
@IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
switch self.segmentedControl?.selectedSegmentIndex {
|
|
||||||
|
|
||||||
case 0?:
|
|
||||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
|
||||||
Where(true).applyToFetchRequest(request)
|
|
||||||
Where(false).applyToFetchRequest(request)
|
|
||||||
|
|
||||||
case 1?:
|
|
||||||
_ = try? dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "emptyStore.sqlite",
|
|
||||||
configuration: "invalidStore"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
case 2?:
|
|
||||||
DispatchQueue.global(qos: .background).async {
|
|
||||||
|
|
||||||
_ = self.dataStack.fetchOne(From<Palette>())
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,424 +0,0 @@
|
|||||||
//
|
|
||||||
// MigrationsDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/06/21.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - MigrationsDemoViewController
|
|
||||||
|
|
||||||
class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewDataSource, UITableViewDelegate {
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
if let segmentedControl = self.segmentedControl {
|
|
||||||
|
|
||||||
for (index, model) in self.models.enumerated() {
|
|
||||||
|
|
||||||
segmentedControl.setTitle(
|
|
||||||
model.label,
|
|
||||||
forSegmentAt: index
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.set(dataStack: nil, model: nil, scrollToSelection: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
let alert = UIAlertController(
|
|
||||||
title: "Migrations Demo",
|
|
||||||
message: "This demo shows how to run progressive migrations and how to support multiple model versions in a single project.\n\nThe persistent store contains 10000 organisms, which gain/lose properties when the migration evolves/devolves them.\n\nYou can use the \"mutate\" button to change an organism's properties then migrate to a different model to see how its value gets affected.",
|
|
||||||
preferredStyle: .alert
|
|
||||||
)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
|
|
||||||
|
|
||||||
let modelMetadata = withExtendedLifetime(DataStack(modelName: "MigrationDemo")) {
|
|
||||||
(dataStack: DataStack) -> ModelMetadata in
|
|
||||||
|
|
||||||
let models = self.models
|
|
||||||
let migrations = try! dataStack.requiredMigrationsForStorage(
|
|
||||||
SQLiteStore(fileName: "MigrationDemo.sqlite")
|
|
||||||
)
|
|
||||||
|
|
||||||
guard let storeVersion = migrations.first?.sourceVersion else {
|
|
||||||
|
|
||||||
return models.first!
|
|
||||||
}
|
|
||||||
for model in models {
|
|
||||||
|
|
||||||
if model.schemaHistory.currentModelVersion == storeVersion {
|
|
||||||
|
|
||||||
return model
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return models.first!
|
|
||||||
}
|
|
||||||
|
|
||||||
self.selectModelVersion(modelMetadata)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: ListObserver
|
|
||||||
|
|
||||||
func listMonitorWillChange(_ monitor: ListMonitor<NSManagedObject>) { }
|
|
||||||
|
|
||||||
func listMonitorDidChange(_ monitor: ListMonitor<NSManagedObject>) {
|
|
||||||
|
|
||||||
if self.lastSelectedIndexPath == nil,
|
|
||||||
let numberOfObjectsInSection = self.listMonitor?.numberOfObjectsInSection(0),
|
|
||||||
numberOfObjectsInSection > 0 {
|
|
||||||
|
|
||||||
self.tableView?.reloadData()
|
|
||||||
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: false)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
self.updateDisplay(reloadData: true, scrollToSelection: true, animated: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: UITableViewDataSource
|
|
||||||
|
|
||||||
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
|
|
||||||
return self.listMonitor?.numberOfObjectsInSection(0) ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc dynamic func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "OrganismTableViewCell", for: indexPath) as! OrganismTableViewCell
|
|
||||||
|
|
||||||
let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? ""
|
|
||||||
cell.dnaLabel?.text = "DNA: \(dna)"
|
|
||||||
cell.mutateButtonHandler = { [weak self] _ -> Void in
|
|
||||||
|
|
||||||
guard let `self` = self,
|
|
||||||
let dataStack = self.dataStack,
|
|
||||||
let organism = self.listMonitor?[indexPath] else {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
|
|
||||||
self.setEnabled(false)
|
|
||||||
dataStack.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
let organism = transaction.edit(organism) as! OrganismProtocol
|
|
||||||
organism.mutate()
|
|
||||||
},
|
|
||||||
completion: { [weak self] _ in
|
|
||||||
|
|
||||||
self?.setEnabled(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDelegate
|
|
||||||
|
|
||||||
@objc dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
|
|
||||||
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
private typealias ModelMetadata = (label: String, entityType: NSManagedObject.Type, schemaHistory: SchemaHistory)
|
|
||||||
|
|
||||||
private let models: [ModelMetadata] = [
|
|
||||||
(
|
|
||||||
label: "Model V1",
|
|
||||||
entityType: OrganismV1.self,
|
|
||||||
schemaHistory: SchemaHistory(
|
|
||||||
modelName: "MigrationDemo",
|
|
||||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
label: "Model V2",
|
|
||||||
entityType: OrganismV2.self,
|
|
||||||
schemaHistory: SchemaHistory(
|
|
||||||
modelName: "MigrationDemo",
|
|
||||||
migrationChain: [
|
|
||||||
"MigrationDemo": "MigrationDemoV2",
|
|
||||||
"MigrationDemoV3": "MigrationDemoV2"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
label: "Model V3",
|
|
||||||
entityType: OrganismV3.self,
|
|
||||||
schemaHistory: SchemaHistory(
|
|
||||||
modelName: "MigrationDemo",
|
|
||||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
private var _listMonitor: ListMonitor<NSManagedObject>?
|
|
||||||
private var listMonitor: ListMonitor<NSManagedObject>? {
|
|
||||||
|
|
||||||
return self._listMonitor
|
|
||||||
}
|
|
||||||
|
|
||||||
private var _dataStack: DataStack?
|
|
||||||
private var dataStack: DataStack? {
|
|
||||||
|
|
||||||
return self._dataStack
|
|
||||||
}
|
|
||||||
|
|
||||||
private var _lastSelectedIndexPath: IndexPath?
|
|
||||||
private var lastSelectedIndexPath: IndexPath? {
|
|
||||||
|
|
||||||
return self._lastSelectedIndexPath
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setSelectedIndexPath(_ indexPath: IndexPath, scrollToSelection: Bool) {
|
|
||||||
|
|
||||||
self._lastSelectedIndexPath = indexPath
|
|
||||||
self.updateDisplay(reloadData: false, scrollToSelection: scrollToSelection, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBOutlet private dynamic weak var headerContainer: UIView?
|
|
||||||
@IBOutlet private dynamic weak var titleLabel: UILabel?
|
|
||||||
@IBOutlet private dynamic weak var organismLabel: UILabel?
|
|
||||||
@IBOutlet private dynamic weak var segmentedControl: UISegmentedControl?
|
|
||||||
@IBOutlet private dynamic weak var progressView: UIProgressView?
|
|
||||||
@IBOutlet private dynamic weak var tableView: UITableView?
|
|
||||||
|
|
||||||
@IBAction private dynamic func segmentedControlValueChanged(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
guard let index = self.segmentedControl?.selectedSegmentIndex else {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.selectModelVersion(self.models[index])
|
|
||||||
}
|
|
||||||
|
|
||||||
private func selectModelVersion(_ model: ModelMetadata) {
|
|
||||||
|
|
||||||
if self.dataStack?.modelVersion == model.schemaHistory.currentModelVersion {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack
|
|
||||||
|
|
||||||
let dataStack = DataStack(schemaHistory: model.schemaHistory)
|
|
||||||
|
|
||||||
self.setEnabled(false)
|
|
||||||
let progress = dataStack.addStorage(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "MigrationDemo.sqlite",
|
|
||||||
migrationMappingProviders: [
|
|
||||||
CustomSchemaMappingProvider(
|
|
||||||
from: "MigrationDemoV3",
|
|
||||||
to: "MigrationDemoV2",
|
|
||||||
entityMappings: [
|
|
||||||
.transformEntity(
|
|
||||||
sourceEntity: "Organism",
|
|
||||||
destinationEntity: "Organism",
|
|
||||||
transformer: { (source, createDestination) in
|
|
||||||
|
|
||||||
let destination = createDestination()
|
|
||||||
destination.enumerateAttributes { (attribute, sourceAttribute) in
|
|
||||||
|
|
||||||
if let sourceAttribute = sourceAttribute {
|
|
||||||
|
|
||||||
destination[attribute] = source[sourceAttribute]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
destination["numberOfFlippers"] = source["numberOfLimbs"]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
completion: { [weak self] (result) -> Void in
|
|
||||||
|
|
||||||
guard let `self` = self else {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
guard case .success = result else {
|
|
||||||
|
|
||||||
self.setEnabled(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
|
|
||||||
|
|
||||||
let count = dataStack.queryValue(
|
|
||||||
From(model.entityType),
|
|
||||||
Select<Int>(.count(#keyPath(OrganismV1.dna))))!
|
|
||||||
if count > 0 {
|
|
||||||
|
|
||||||
self.setEnabled(true)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
for i: Int64 in 0 ..< 20 {
|
|
||||||
|
|
||||||
dataStack.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
for j: Int64 in 0 ..< 500 {
|
|
||||||
|
|
||||||
let organism = transaction.create(Into(model.entityType)) as! OrganismProtocol
|
|
||||||
organism.dna = (i * 500) + j + 1
|
|
||||||
organism.mutate()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
dataStack.perform(
|
|
||||||
asynchronous: { _ in },
|
|
||||||
completion: { [weak self] _ in
|
|
||||||
|
|
||||||
self?.setEnabled(true)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if let progress = progress {
|
|
||||||
|
|
||||||
progress.setProgressHandler { [weak self] (progress) -> Void in
|
|
||||||
|
|
||||||
self?.reloadTableHeaderWithProgress(progress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setEnabled(_ enabled: Bool) {
|
|
||||||
|
|
||||||
UIView.animate(
|
|
||||||
withDuration: 0.2,
|
|
||||||
delay: 0,
|
|
||||||
options: .beginFromCurrentState,
|
|
||||||
animations: { () -> Void in
|
|
||||||
|
|
||||||
let navigationItem = self.navigationItem
|
|
||||||
navigationItem.leftBarButtonItem?.isEnabled = enabled
|
|
||||||
navigationItem.rightBarButtonItem?.isEnabled = enabled
|
|
||||||
navigationItem.hidesBackButton = !enabled
|
|
||||||
|
|
||||||
self.segmentedControl?.isEnabled = enabled
|
|
||||||
|
|
||||||
if let tableView = self.tableView {
|
|
||||||
|
|
||||||
tableView.alpha = enabled ? 1.0 : 0.5
|
|
||||||
tableView.isUserInteractionEnabled = enabled
|
|
||||||
}
|
|
||||||
},
|
|
||||||
completion: nil
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func set(dataStack: DataStack?, model: ModelMetadata?, scrollToSelection: Bool) {
|
|
||||||
|
|
||||||
if let dataStack = dataStack, let model = model {
|
|
||||||
|
|
||||||
self.segmentedControl?.selectedSegmentIndex = self.models
|
|
||||||
.index(
|
|
||||||
where: { (_, _, schemaHistory) -> Bool in
|
|
||||||
|
|
||||||
schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
|
|
||||||
}
|
|
||||||
)!
|
|
||||||
|
|
||||||
self._dataStack = dataStack
|
|
||||||
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
|
|
||||||
listMonitor.addObserver(self)
|
|
||||||
self._listMonitor = listMonitor
|
|
||||||
|
|
||||||
if self.lastSelectedIndexPath == nil {
|
|
||||||
|
|
||||||
if listMonitor.numberOfObjectsInSection(0) > 0 {
|
|
||||||
|
|
||||||
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
self.segmentedControl?.selectedSegmentIndex = UISegmentedControlNoSegment
|
|
||||||
self._listMonitor = nil
|
|
||||||
self._dataStack = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
self.updateDisplay(reloadData: true, scrollToSelection: scrollToSelection, animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func reloadTableHeaderWithProgress(_ progress: Progress) {
|
|
||||||
|
|
||||||
self.progressView?.setProgress(Float(progress.fractionCompleted), animated: true)
|
|
||||||
self.titleLabel?.text = "Migrating: \(progress.localizedDescription ?? "")"
|
|
||||||
self.organismLabel?.text = "Progressive step \(progress.localizedAdditionalDescription ?? "")"
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateDisplay(reloadData: Bool, scrollToSelection: Bool, animated: Bool) {
|
|
||||||
|
|
||||||
var lines = [String]()
|
|
||||||
var organismType = ""
|
|
||||||
if let indexPath = self.lastSelectedIndexPath, let organism = self.listMonitor?[indexPath] {
|
|
||||||
|
|
||||||
for property in organism.entity.properties {
|
|
||||||
|
|
||||||
let value = organism.value(forKey: property.name) ?? NSNull()
|
|
||||||
lines.append("\(property.name): \(value)")
|
|
||||||
}
|
|
||||||
organismType = organism.entity.managedObjectClassName
|
|
||||||
}
|
|
||||||
|
|
||||||
self.titleLabel?.text = organismType
|
|
||||||
self.organismLabel?.text = lines.joined(separator: "\n")
|
|
||||||
self.progressView?.progress = 0
|
|
||||||
|
|
||||||
self.headerContainer?.setNeedsLayout()
|
|
||||||
|
|
||||||
guard let tableView = self.tableView else {
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if reloadData {
|
|
||||||
|
|
||||||
tableView.reloadData()
|
|
||||||
}
|
|
||||||
|
|
||||||
tableView.layoutIfNeeded()
|
|
||||||
|
|
||||||
if let indexPath = self.lastSelectedIndexPath,
|
|
||||||
indexPath.row < tableView.numberOfRows(inSection: 0) {
|
|
||||||
|
|
||||||
tableView.selectRow(at: indexPath,
|
|
||||||
animated: scrollToSelection && animated,
|
|
||||||
scrollPosition: scrollToSelection ? .middle : .none
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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()
|
|
||||||
}
|
|
||||||
@@ -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?()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
@@ -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)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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 {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -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 {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,196 +0,0 @@
|
|||||||
//
|
|
||||||
// StackSetupDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/24.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
private struct Static {
|
|
||||||
|
|
||||||
static let maleConfiguration = "MaleAccounts"
|
|
||||||
static let femaleConfiguration = "FemaleAccounts"
|
|
||||||
|
|
||||||
static let facebookStack: DataStack = {
|
|
||||||
|
|
||||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
|
||||||
try! dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "AccountsDemo_FB_Male.sqlite",
|
|
||||||
configuration: maleConfiguration,
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try! dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "AccountsDemo_FB_Female.sqlite",
|
|
||||||
configuration: femaleConfiguration,
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
_ = try? dataStack.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
transaction.deleteAll(From<UserAccount>())
|
|
||||||
|
|
||||||
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
|
|
||||||
account1.accountType = "Facebook"
|
|
||||||
account1.name = "John Smith HCD"
|
|
||||||
account1.friends = 42
|
|
||||||
|
|
||||||
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
|
|
||||||
account2.accountType = "Facebook"
|
|
||||||
account2.name = "Jane Doe HCD"
|
|
||||||
account2.friends = 314
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return dataStack
|
|
||||||
}()
|
|
||||||
|
|
||||||
static let twitterStack: DataStack = {
|
|
||||||
|
|
||||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
|
||||||
try! dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "AccountsDemo_TW_Male.sqlite",
|
|
||||||
configuration: maleConfiguration,
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try! dataStack.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "AccountsDemo_TW_Female.sqlite",
|
|
||||||
configuration: femaleConfiguration,
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
_ = try? dataStack.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
transaction.deleteAll(From<UserAccount>())
|
|
||||||
|
|
||||||
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
|
|
||||||
account1.accountType = "Twitter"
|
|
||||||
account1.name = "#johnsmith_hcd"
|
|
||||||
account1.friends = 7
|
|
||||||
|
|
||||||
let account2 = transaction.create(Into<FemaleAccount>(femaleConfiguration))
|
|
||||||
account2.accountType = "Twitter"
|
|
||||||
account2.name = "#janedoe_hcd"
|
|
||||||
account2.friends = 100
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return dataStack
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - StackSetupDemoViewController
|
|
||||||
|
|
||||||
class StackSetupDemoViewController: UITableViewController {
|
|
||||||
|
|
||||||
let accounts = [
|
|
||||||
Static.facebookStack.fetchAll(From(UserAccount.self)) ?? [],
|
|
||||||
Static.twitterStack.fetchAll(From(UserAccount.self)) ?? []
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
|
|
||||||
self.tableView.reloadData()
|
|
||||||
|
|
||||||
let indexPath = IndexPath(row: 0, section: 0)
|
|
||||||
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
|
|
||||||
self.updateDetails(account: self.accounts[indexPath.section][indexPath.row])
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
let alert = UIAlertController(
|
|
||||||
title: "Setup Demo",
|
|
||||||
message: "This demo shows how to initialize 2 DataStacks with 2 configurations each, for a total of 4 SQLite files, each with 1 instance of a \"UserAccount\" entity.",
|
|
||||||
preferredStyle: .alert
|
|
||||||
)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDataSource
|
|
||||||
|
|
||||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
|
||||||
|
|
||||||
return self.accounts.count
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
||||||
|
|
||||||
return self.accounts[section].count
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
|
||||||
|
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
|
|
||||||
|
|
||||||
let account = self.accounts[indexPath.section][indexPath.row]
|
|
||||||
cell.textLabel?.text = account.name
|
|
||||||
cell.detailTextLabel?.text = "\(account.friends) friends"
|
|
||||||
|
|
||||||
return cell
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UITableViewDelegate
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
||||||
|
|
||||||
let account = self.accounts[indexPath.section][indexPath.row]
|
|
||||||
self.updateDetails(account: account)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
|
||||||
|
|
||||||
switch section {
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
let count = self.accounts[section].count
|
|
||||||
return "Facebook Accounts (\(count) users)"
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
let count = self.accounts[section].count
|
|
||||||
return "Twitter Accounts (\(count) users)"
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
@IBOutlet private dynamic weak var accountTypeLabel: UILabel?
|
|
||||||
@IBOutlet private dynamic weak var nameLabel: UILabel?
|
|
||||||
@IBOutlet private dynamic weak var friendsLabel: UILabel?
|
|
||||||
|
|
||||||
private func updateDetails(account: UserAccount) {
|
|
||||||
|
|
||||||
self.accountTypeLabel?.text = account.accountType
|
|
||||||
self.nameLabel?.text = account.name
|
|
||||||
self.friendsLabel?.text = "\(account.friends) friends"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
//
|
|
||||||
// TransactionsDemoViewController.swift
|
|
||||||
// CoreStoreDemo
|
|
||||||
//
|
|
||||||
// Created by John Rommel Estropia on 2015/05/24.
|
|
||||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import CoreLocation
|
|
||||||
import MapKit
|
|
||||||
import AddressBookUI
|
|
||||||
import CoreStore
|
|
||||||
|
|
||||||
|
|
||||||
private struct Static {
|
|
||||||
|
|
||||||
static let placeController: ObjectMonitor<Place> = {
|
|
||||||
|
|
||||||
try! CoreStore.addStorageAndWait(
|
|
||||||
SQLiteStore(
|
|
||||||
fileName: "PlaceDemo.sqlite",
|
|
||||||
configuration: "TransactionsDemo",
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
var place = CoreStore.fetchOne(From<Place>())
|
|
||||||
if place == nil {
|
|
||||||
|
|
||||||
_ = try? CoreStore.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
let place = transaction.create(Into<Place>())
|
|
||||||
place.setInitialValues()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
place = CoreStore.fetchOne(From<Place>())
|
|
||||||
}
|
|
||||||
|
|
||||||
return CoreStore.monitorObject(place!)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - TransactionsDemoViewController
|
|
||||||
|
|
||||||
class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, ObjectObserver {
|
|
||||||
|
|
||||||
// MARK: NSObject
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
|
|
||||||
Static.placeController.removeObserver(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: UIViewController
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
let longPressGesture = UILongPressGestureRecognizer(
|
|
||||||
target: self,
|
|
||||||
action: #selector(self.longPressGestureRecognized(_:))
|
|
||||||
)
|
|
||||||
self.mapView?.addGestureRecognizer(longPressGesture)
|
|
||||||
|
|
||||||
Static.placeController.addObserver(self)
|
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
||||||
barButtonSystemItem: .refresh,
|
|
||||||
target: self,
|
|
||||||
action: #selector(self.refreshButtonTapped(_:))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
let alert = UIAlertController(
|
|
||||||
title: "Transactions Demo",
|
|
||||||
message: "This demo shows how to use the 3 types of transactions to save updates: synchronous, asynchronous, and unsafe.\n\nTap and hold on the map to change the pin location.",
|
|
||||||
preferredStyle: .alert
|
|
||||||
)
|
|
||||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
|
|
||||||
self.present(alert, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
|
|
||||||
if let mapView = self.mapView, let place = Static.placeController.object {
|
|
||||||
|
|
||||||
mapView.addAnnotation(place)
|
|
||||||
mapView.setCenter(place.coordinate, animated: false)
|
|
||||||
mapView.selectAnnotation(place, animated: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: MKMapViewDelegate
|
|
||||||
|
|
||||||
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
|
||||||
|
|
||||||
let identifier = "MKAnnotationView"
|
|
||||||
var annotationView: MKPinAnnotationView! = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
|
|
||||||
if annotationView == nil {
|
|
||||||
|
|
||||||
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
|
|
||||||
annotationView.isEnabled = true
|
|
||||||
annotationView.canShowCallout = true
|
|
||||||
annotationView.animatesDrop = true
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
annotationView.annotation = annotation
|
|
||||||
}
|
|
||||||
|
|
||||||
return annotationView
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: ObjectObserver
|
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, willUpdateObject object: Place) {
|
|
||||||
|
|
||||||
// none
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPath>) {
|
|
||||||
|
|
||||||
if let mapView = self.mapView {
|
|
||||||
|
|
||||||
mapView.removeAnnotations(mapView.annotations)
|
|
||||||
mapView.addAnnotation(object)
|
|
||||||
mapView.setCenter(object.coordinate, animated: true)
|
|
||||||
mapView.selectAnnotation(object, animated: true)
|
|
||||||
|
|
||||||
if changedPersistentKeys.contains(#keyPath(Place.latitude)) || changedPersistentKeys.contains(#keyPath(Place.longitude)) {
|
|
||||||
|
|
||||||
self.geocode(place: object)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didDeleteObject object: Place) {
|
|
||||||
|
|
||||||
// none
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
var geocoder: CLGeocoder?
|
|
||||||
|
|
||||||
@IBOutlet weak var mapView: MKMapView?
|
|
||||||
|
|
||||||
@IBAction dynamic func longPressGestureRecognized(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
if let mapView = self.mapView,
|
|
||||||
let gesture = sender as? UILongPressGestureRecognizer,
|
|
||||||
gesture.state == .began {
|
|
||||||
|
|
||||||
let coordinate = mapView.convert(
|
|
||||||
gesture.location(in: mapView),
|
|
||||||
toCoordinateFrom: mapView
|
|
||||||
)
|
|
||||||
CoreStore.perform(
|
|
||||||
asynchronous: { (transaction) in
|
|
||||||
|
|
||||||
let place = transaction.edit(Static.placeController.object)
|
|
||||||
place?.coordinate = coordinate
|
|
||||||
},
|
|
||||||
completion: { _ in }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) {
|
|
||||||
|
|
||||||
_ = try? CoreStore.perform(
|
|
||||||
synchronous: { (transaction) in
|
|
||||||
|
|
||||||
let place = transaction.edit(Static.placeController.object)
|
|
||||||
place?.setInitialValues()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func geocode(place: Place) {
|
|
||||||
|
|
||||||
let transaction = CoreStore.beginUnsafe()
|
|
||||||
|
|
||||||
self.geocoder?.cancelGeocode()
|
|
||||||
|
|
||||||
let geocoder = CLGeocoder()
|
|
||||||
self.geocoder = geocoder
|
|
||||||
geocoder.reverseGeocodeLocation(
|
|
||||||
CLLocation(latitude: place.latitude, longitude: place.longitude),
|
|
||||||
completionHandler: { [weak self] (placemarks, error) -> Void in
|
|
||||||
|
|
||||||
if let placemark = placemarks?.first, let addressDictionary = placemark.addressDictionary {
|
|
||||||
|
|
||||||
let place = transaction.edit(Static.placeController.object)
|
|
||||||
place?.title = placemark.name
|
|
||||||
place?.subtitle = ABCreateStringWithAddressDictionary(addressDictionary, true)
|
|
||||||
transaction.commit { (_) -> Void in }
|
|
||||||
}
|
|
||||||
|
|
||||||
self?.geocoder = nil
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
// BaseTestCase.swift
|
// BaseTestCase.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -28,6 +28,17 @@ import XCTest
|
|||||||
@testable
|
@testable
|
||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
#if !SWIFT_PACKAGE
|
||||||
|
|
||||||
|
extension Bundle {
|
||||||
|
|
||||||
|
static var module: Bundle {
|
||||||
|
return Bundle(for: BaseTestCase.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// MARK: - BaseTestCase
|
// MARK: - BaseTestCase
|
||||||
|
|
||||||
@@ -36,12 +47,11 @@ class BaseTestCase: XCTestCase {
|
|||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
@discardableResult
|
func prepareStack(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) throws -> Void) {
|
||||||
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
|
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -51,36 +61,66 @@ class BaseTestCase: XCTestCase {
|
|||||||
SQLiteStore(
|
SQLiteStore(
|
||||||
fileURL: SQLiteStore.defaultRootDirectory
|
fileURL: SQLiteStore.defaultRootDirectory
|
||||||
.appendingPathComponent(UUID().uuidString)
|
.appendingPathComponent(UUID().uuidString)
|
||||||
.appendingPathComponent("\(type(of: self))_\(($0 ?? "-null-")).sqlite"),
|
.appendingPathComponent("\(Self.self)_\(($0 ?? "-null-")).sqlite"),
|
||||||
configuration: $0,
|
configuration: $0,
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
try closure(stack)
|
||||||
}
|
}
|
||||||
catch let error as NSError {
|
catch let error as NSError {
|
||||||
|
|
||||||
XCTFail(error.coreStoreDumpString)
|
XCTFail(error.coreStoreDumpString)
|
||||||
}
|
}
|
||||||
return closure(stack)
|
self.addTeardownBlock {
|
||||||
|
stack.unsafeRemoveAllPersistentStoresAndWait()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () -> T) -> T {
|
func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () throws -> T) rethrows -> T {
|
||||||
|
|
||||||
CoreStore.logger = TestLogger(self.prepareLoggerExpectations(expectations))
|
CoreStoreDefaults.logger = TestLogger(self.prepareLoggerExpectations(expectations))
|
||||||
defer {
|
defer {
|
||||||
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
CoreStore.logger = TestLogger([:])
|
CoreStoreDefaults.logger = TestLogger([:])
|
||||||
}
|
}
|
||||||
return closure()
|
return try closure()
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
func expectLogger(_ expectations: [TestLogger.Expectation: XCTestExpectation]) {
|
func expectLogger(_ expectations: [TestLogger.Expectation: XCTestExpectation]) {
|
||||||
|
|
||||||
CoreStore.logger = TestLogger(expectations)
|
CoreStoreDefaults.logger = TestLogger(expectations)
|
||||||
|
}
|
||||||
|
|
||||||
|
@nonobjc
|
||||||
|
func expectError<T>(code: CoreStoreErrorCode, closure: () throws -> T) {
|
||||||
|
|
||||||
|
CoreStoreDefaults.logger = TestLogger(self.prepareLoggerExpectations([.logError]))
|
||||||
|
defer {
|
||||||
|
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
|
CoreStoreDefaults.logger = TestLogger([:])
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
|
||||||
|
_ = try closure()
|
||||||
|
}
|
||||||
|
catch let error as CoreStoreError {
|
||||||
|
|
||||||
|
if error.errorCode == code.rawValue {
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
XCTFail("Expected error code \(code) different from actual error: \((error as NSError).coreStoreDumpString)")
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail("Error not wrapped as \(Internals.typeName(CoreStoreError.self)): \((error as NSError).coreStoreDumpString)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
@@ -112,12 +152,12 @@ class BaseTestCase: XCTestCase {
|
|||||||
|
|
||||||
super.setUp()
|
super.setUp()
|
||||||
self.deleteStores()
|
self.deleteStores()
|
||||||
CoreStore.logger = TestLogger([:])
|
CoreStoreDefaults.logger = TestLogger([:])
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
|
|
||||||
CoreStore.logger = DefaultLogger()
|
CoreStoreDefaults.logger = DefaultLogger()
|
||||||
self.deleteStores()
|
self.deleteStores()
|
||||||
super.tearDown()
|
super.tearDown()
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,25 @@
|
|||||||
// BaseTestDataTestCase.swift
|
// BaseTestDataTestCase.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Created by John Rommel Estropia on 2016/06/11.
|
// Copyright © 2018 John Rommel Estropia
|
||||||
// Copyright © 2016 John Rommel Estropia. All rights reserved.
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
@@ -17,7 +34,7 @@ import CoreStore
|
|||||||
class BaseTestDataTestCase: BaseTestCase {
|
class BaseTestDataTestCase: BaseTestCase {
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
let dateFormatter: DateFormatter = cs_lazy {
|
let dateFormatter: DateFormatter = Internals.with {
|
||||||
|
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
//
|
|
||||||
// BridgingTests.m
|
|
||||||
// CoreStore
|
|
||||||
//
|
|
||||||
// Copyright © 2016 John Rommel Estropia
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "BridgingTests.h"
|
|
||||||
#import <CoreStore/CoreStore.h>
|
|
||||||
#import <CoreStore/CoreStore-Swift.h>
|
|
||||||
#import "CoreStoreTests-Swift.h"
|
|
||||||
|
|
||||||
@import CoreData;
|
|
||||||
|
|
||||||
// MARK: - BridgingTests
|
|
||||||
|
|
||||||
@implementation BridgingTests
|
|
||||||
|
|
||||||
- (void)test_ThatFlags_HaveCorrectValues {
|
|
||||||
|
|
||||||
XCTAssertEqual(CSLocalStorageOptionsNone, 0);
|
|
||||||
XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1);
|
|
||||||
XCTAssertEqual(CSLocalStorageOptionsPreventProgressiveMigration, 2);
|
|
||||||
XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatKeyPaths_AreCorrect {
|
|
||||||
|
|
||||||
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testNumber), @"testNumber");
|
|
||||||
XCTAssertEqualObjects(CSKeyPath(TestEntity1, testString), @"testString");
|
|
||||||
XCTAssertEqualObjects(CSKeyPathOperator(count, TestEntity1, testString), @"@count.testString");
|
|
||||||
XCTAssertEqualObjects(CSKeyPathOperator(max, TestEntity1, testNumber), @"@max.testNumber");
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatFromClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
{
|
|
||||||
CSFrom *from = CSFromClass([TestEntity1 class]);
|
|
||||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
|
||||||
XCTAssertNil(from.configurations);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSFrom *from = CSFromClass([TestEntity1 class], [NSNull null]);
|
|
||||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
|
||||||
|
|
||||||
NSArray *configurations = @[[NSNull null]];
|
|
||||||
XCTAssertEqualObjects(from.configurations, configurations);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSFrom *from = CSFromClass([TestEntity1 class], @"Config1");
|
|
||||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
|
||||||
|
|
||||||
NSArray *configurations = @[@"Config1"];
|
|
||||||
XCTAssertEqualObjects(from.configurations, configurations);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSFrom *from = CSFromClass([TestEntity1 class], @[[NSNull null], @"Config2"]);
|
|
||||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
|
||||||
|
|
||||||
NSArray *configurations = @[[NSNull null], @"Config2"];
|
|
||||||
XCTAssertEqualObjects(from.configurations, configurations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatWhereClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
{
|
|
||||||
CSWhere *where = CSWhereFormat(@"%K == %@", @"key", @"value");
|
|
||||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
|
|
||||||
XCTAssertEqualObjects(where.predicate, predicate);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSWhere *where = CSWhereValue(YES);
|
|
||||||
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
|
|
||||||
XCTAssertEqualObjects(where.predicate, predicate);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSWhere *where = CSWherePredicate([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
|
|
||||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
|
|
||||||
XCTAssertEqualObjects(where.predicate, predicate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatOrderByClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
{
|
|
||||||
CSOrderBy *orderBy = CSOrderByKey(CSSortAscending(@"key"));
|
|
||||||
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSOrderBy *orderBy = CSOrderByKey(CSSortDescending(@"key"));
|
|
||||||
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSOrderBy *orderBy = CSOrderByKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil);
|
|
||||||
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES],
|
|
||||||
[NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]];
|
|
||||||
XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatGroupByClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
{
|
|
||||||
CSGroupBy *groupBy = CSGroupByKeyPath(@"key");
|
|
||||||
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSGroupBy *groupBy = CSGroupByKeyPaths(@[@"key1", @"key2"]);
|
|
||||||
|
|
||||||
NSArray *keyPaths = @[@"key1", @"key2"];
|
|
||||||
XCTAssertEqualObjects(groupBy.keyPaths, keyPaths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatTweakClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
CSTweak *tweak = CSTweakRequest(^(NSFetchRequest * _Nonnull fetchRequest) {
|
|
||||||
|
|
||||||
fetchRequest.fetchLimit = 100;
|
|
||||||
});
|
|
||||||
NSFetchRequest *request = [NSFetchRequest new];
|
|
||||||
tweak.block(request);
|
|
||||||
XCTAssertEqual(request.fetchLimit, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatIntoClauses_BridgeCorrectly {
|
|
||||||
|
|
||||||
{
|
|
||||||
CSInto *into = CSIntoClass([TestEntity1 class]);
|
|
||||||
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSInto *into = CSIntoClass([TestEntity1 class], [NSNull null]);
|
|
||||||
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
|
|
||||||
XCTAssertNil(into.configuration);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CSInto *into = CSIntoClass([TestEntity1 class], @"Config1");
|
|
||||||
XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]);
|
|
||||||
XCTAssertEqualObjects(into.configuration, @"Config1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatDataStacks_BridgeCorrectly {
|
|
||||||
|
|
||||||
CSDataStack *dataStack = [[CSDataStack alloc]
|
|
||||||
initWithModelName:@"Model"
|
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
|
||||||
versionChain:nil];
|
|
||||||
XCTAssertNotNil(dataStack);
|
|
||||||
|
|
||||||
[CSCoreStore setDefaultStack:dataStack];
|
|
||||||
XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatStorages_BridgeCorrectly {
|
|
||||||
|
|
||||||
NSError *memoryError;
|
|
||||||
CSInMemoryStore *memoryStorage = [CSCoreStore
|
|
||||||
addInMemoryStorageAndWait:[CSInMemoryStore new]
|
|
||||||
error:&memoryError];
|
|
||||||
XCTAssertNotNil(memoryStorage);
|
|
||||||
XCTAssertEqualObjects([[memoryStorage class] storeType], [CSInMemoryStore storeType]);
|
|
||||||
XCTAssertEqualObjects([[memoryStorage class] storeType], NSInMemoryStoreType);
|
|
||||||
XCTAssertNil(memoryStorage.configuration);
|
|
||||||
XCTAssertNil(memoryStorage.storeOptions);
|
|
||||||
XCTAssertNil(memoryError);
|
|
||||||
|
|
||||||
NSError *sqliteError;
|
|
||||||
CSSQLiteStore *sqliteStorage = [CSCoreStore
|
|
||||||
addSQLiteStorageAndWait:[CSSQLiteStore new]
|
|
||||||
error:&sqliteError];
|
|
||||||
XCTAssertNotNil(sqliteStorage);
|
|
||||||
XCTAssertEqualObjects([[sqliteStorage class] storeType], [CSSQLiteStore storeType]);
|
|
||||||
XCTAssertEqualObjects([[sqliteStorage class] storeType], NSSQLiteStoreType);
|
|
||||||
XCTAssertNil(sqliteStorage.configuration);
|
|
||||||
XCTAssertEqualObjects(sqliteStorage.storeOptions, @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" } });
|
|
||||||
XCTAssertNil(sqliteError);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)test_ThatTransactions_BridgeCorrectly {
|
|
||||||
|
|
||||||
[CSCoreStore
|
|
||||||
setDefaultStack:[[CSDataStack alloc]
|
|
||||||
initWithModelName:@"Model"
|
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
|
||||||
versionChain:nil]];
|
|
||||||
[CSCoreStore
|
|
||||||
addInMemoryStorageAndWait:[CSInMemoryStore new]
|
|
||||||
error:nil];
|
|
||||||
|
|
||||||
{
|
|
||||||
CSUnsafeDataTransaction *transaction = [CSCoreStore beginUnsafe];
|
|
||||||
XCTAssertNotNil(transaction);
|
|
||||||
XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]);
|
|
||||||
NSError *error;
|
|
||||||
BOOL result = [transaction commitAndWaitWithError:&error];
|
|
||||||
XCTAssertTrue(result);
|
|
||||||
XCTAssertNil(error);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"sync"];
|
|
||||||
NSError *error;
|
|
||||||
BOOL result = [CSCoreStore
|
|
||||||
beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) {
|
|
||||||
|
|
||||||
XCTAssertNotNil(transaction);
|
|
||||||
XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]);
|
|
||||||
NSError *error;
|
|
||||||
XCTAssertTrue([transaction commitAndWaitWithError:&error]);
|
|
||||||
XCTAssertNil(error);
|
|
||||||
[expectation fulfill];
|
|
||||||
}
|
|
||||||
error:&error];
|
|
||||||
XCTAssertTrue(result);
|
|
||||||
XCTAssertNil(error);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"async"];
|
|
||||||
[CSCoreStore beginAsynchronous:^(CSAsynchronousDataTransaction * _Nonnull transaction) {
|
|
||||||
|
|
||||||
XCTAssertNotNil(transaction);
|
|
||||||
XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]);
|
|
||||||
[transaction
|
|
||||||
commitWithSuccess:^{
|
|
||||||
|
|
||||||
[expectation fulfill];
|
|
||||||
}
|
|
||||||
failure:^(CSError *error){
|
|
||||||
|
|
||||||
XCTFail();
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
[self waitForExpectationsWithTimeout:10 handler:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
#if TARGET_OS_IOS || TARGET_OS_WATCHOS || TARGET_OS_TV
|
|
||||||
|
|
||||||
- (void)test_ThatDataStacks_CanCreateCustomFetchedResultsControllers {
|
|
||||||
|
|
||||||
[CSCoreStore
|
|
||||||
setDefaultStack:[[CSDataStack alloc]
|
|
||||||
initWithModelName:@"Model"
|
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
|
||||||
versionChain:nil]];
|
|
||||||
[CSCoreStore
|
|
||||||
addInMemoryStorageAndWait:[CSInMemoryStore new]
|
|
||||||
error:nil];
|
|
||||||
NSFetchedResultsController *controller =
|
|
||||||
[[CSCoreStore defaultStack]
|
|
||||||
createFetchedResultsControllerFrom:CSFromClass([TestEntity1 class])
|
|
||||||
sectionBy:[CSSectionBy keyPath:CSKeyPath(TestEntity1, testString)]
|
|
||||||
fetchClauses:@[CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100),
|
|
||||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil),
|
|
||||||
CSTweakRequest(^(NSFetchRequest *fetchRequest) { fetchRequest.fetchLimit = 10; })]];
|
|
||||||
|
|
||||||
XCTAssertNotNil(controller);
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.entity.managedObjectClassName, [[TestEntity1 class] description]);
|
|
||||||
XCTAssertEqualObjects(controller.sectionNameKeyPath, CSKeyPath(TestEntity1, testString));
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.predicate,
|
|
||||||
CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100).predicate);
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.sortDescriptors,
|
|
||||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil).sortDescriptors);
|
|
||||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// ConvenienceTests.swift
|
// ConvenienceTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,13 +23,15 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
// MARK: - ConvenienceTests
|
// MARK: - ConvenienceTests
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
class ConvenienceTests: BaseTestCase {
|
class ConvenienceTests: BaseTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -40,8 +42,8 @@ class ConvenienceTests: BaseTestCase {
|
|||||||
let controller = stack.createFetchedResultsController(
|
let controller = stack.createFetchedResultsController(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testString)),
|
SectionBy(#keyPath(TestEntity1.testString)),
|
||||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
|
||||||
Tweak { $0.fetchLimit = 10 }
|
Tweak { $0.fetchLimit = 10 }
|
||||||
)
|
)
|
||||||
XCTAssertEqual(controller.managedObjectContext, stack.mainContext)
|
XCTAssertEqual(controller.managedObjectContext, stack.mainContext)
|
||||||
@@ -49,11 +51,11 @@ class ConvenienceTests: BaseTestCase {
|
|||||||
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
controller.fetchRequest.sortDescriptors!,
|
controller.fetchRequest.sortDescriptors!,
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||||
)
|
)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
controller.fetchRequest.predicate,
|
controller.fetchRequest.predicate,
|
||||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||||
)
|
)
|
||||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
||||||
}
|
}
|
||||||
@@ -64,13 +66,13 @@ class ConvenienceTests: BaseTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
_ = withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
|
withExtendedLifetime(stack.beginUnsafe()) { (transaction: UnsafeDataTransaction) in
|
||||||
|
|
||||||
let controller = transaction.createFetchedResultsController(
|
let controller = transaction.createFetchedResultsController(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testString)),
|
SectionBy(#keyPath(TestEntity1.testString)),
|
||||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
|
||||||
Tweak { $0.fetchLimit = 10 }
|
Tweak { $0.fetchLimit = 10 }
|
||||||
)
|
)
|
||||||
XCTAssertEqual(controller.managedObjectContext, transaction.context)
|
XCTAssertEqual(controller.managedObjectContext, transaction.context)
|
||||||
@@ -78,11 +80,11 @@ class ConvenienceTests: BaseTestCase {
|
|||||||
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
controller.fetchRequest.sortDescriptors!,
|
controller.fetchRequest.sortDescriptors!,
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||||
)
|
)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
controller.fetchRequest.predicate,
|
controller.fetchRequest.predicate,
|
||||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||||
)
|
)
|
||||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// DynamicModelTests.swift
|
// DynamicModelTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2017 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -28,32 +28,160 @@ import XCTest
|
|||||||
@testable
|
@testable
|
||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
typealias Color = NSColor
|
||||||
|
|
||||||
|
#else
|
||||||
|
typealias Color = UIColor
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class Animal: CoreStoreObject {
|
class Animal: CoreStoreObject {
|
||||||
|
|
||||||
let species = Value.Required<String>("species", default: "Swift")
|
@Field.Stored("species")
|
||||||
let master = Relationship.ToOne<Person>("master")
|
var species: String = "Swift"
|
||||||
let color = Transformable.Optional<UIColor>("color")
|
|
||||||
|
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
|
||||||
|
var color: Color? = .blue
|
||||||
|
|
||||||
|
@Field.Relationship("master")
|
||||||
|
var master: Person?
|
||||||
}
|
}
|
||||||
|
|
||||||
class Dog: Animal {
|
class Dog: Animal {
|
||||||
|
|
||||||
let nickname = Value.Optional<String>("nickname")
|
static let commonNicknames = ["Spot", "Benjie", "Max", "Milo"]
|
||||||
let age = Value.Required<Int>("age", default: 1)
|
|
||||||
let friends = Relationship.ToManyOrdered<Dog>("friends")
|
@Field.Stored(
|
||||||
let friendedBy = Relationship.ToManyUnordered<Dog>("friendedBy", inverse: { $0.friends })
|
"nickname",
|
||||||
|
dynamicInitialValue: {
|
||||||
|
commonNicknames.randomElement()!
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var nickname: String
|
||||||
|
|
||||||
|
@Field.Stored("age")
|
||||||
|
var age: Int = 1
|
||||||
|
|
||||||
|
@Field.Relationship("friends")
|
||||||
|
var friends: [Dog]
|
||||||
|
|
||||||
|
@Field.Relationship("friendedBy", inverse: \.$friends)
|
||||||
|
var friendedBy: Set<Dog>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CustomType {
|
||||||
|
var string = "customString"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Job: String, CaseIterable {
|
||||||
|
|
||||||
|
case unemployed
|
||||||
|
case engineer
|
||||||
|
case doctor
|
||||||
|
case lawyer
|
||||||
|
|
||||||
|
init?(data: Data) {
|
||||||
|
|
||||||
|
guard
|
||||||
|
let rawValue = String(data: data, encoding: .utf8),
|
||||||
|
let value = Self.init(rawValue: rawValue)
|
||||||
|
else {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
self = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func toData() -> Data {
|
||||||
|
|
||||||
|
return Data(self.rawValue.utf8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person: CoreStoreObject {
|
class Person: CoreStoreObject {
|
||||||
let title = Value.Required<String>("title", default: "Mr.")
|
|
||||||
let name = Value.Required<String>(
|
@Field.Stored(
|
||||||
"name",
|
"title",
|
||||||
customGetter: { (`self`, getValue) in
|
customSetter: { (object, field, newValue) in
|
||||||
|
field.primitiveValue = newValue
|
||||||
return "\(self.title.value) \(getValue())"
|
object.$displayName.primitiveValue = nil
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
var title: String = "Mr."
|
||||||
|
|
||||||
|
@Field.Stored(
|
||||||
|
"name",
|
||||||
|
customSetter: { (object, field, newValue) in
|
||||||
|
field.primitiveValue = newValue
|
||||||
|
object.$displayName.primitiveValue = nil
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var name: String = ""
|
||||||
|
|
||||||
|
@Field.Virtual(
|
||||||
|
"displayName",
|
||||||
|
customGetter: Person.getDisplayName(_:_:),
|
||||||
|
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
|
||||||
|
)
|
||||||
|
var displayName: String?
|
||||||
|
|
||||||
|
@Field.Virtual(
|
||||||
|
"customType",
|
||||||
|
customGetter: { (object, field) in
|
||||||
|
|
||||||
|
if let value = field.primitiveValue {
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
let value = CustomType()
|
||||||
|
field.primitiveValue = value
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var customField: CustomType
|
||||||
|
|
||||||
|
@Field.Coded(
|
||||||
|
"job",
|
||||||
|
coder: (
|
||||||
|
encode: { $0.toData() },
|
||||||
|
decode: { $0.flatMap(Job.init(data:)) ?? .unemployed }
|
||||||
|
),
|
||||||
|
dynamicInitialValue: {
|
||||||
|
Job.allCases.randomElement()!
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var job: Job
|
||||||
|
|
||||||
|
@Field.Relationship("spouse")
|
||||||
|
var spouse: Person?
|
||||||
|
|
||||||
|
@Field.Relationship("pets", inverse: \.$master)
|
||||||
|
var pets: Set<Animal>
|
||||||
|
|
||||||
|
@Field.Relationship("_spouseInverse", inverse: \.$spouse)
|
||||||
|
private var spouseInverse: Person?
|
||||||
|
|
||||||
|
private static func getDisplayName(_ object: ObjectProxy<Person>, _ field: ObjectProxy<Person>.FieldProxy<String?>) -> String? {
|
||||||
|
|
||||||
|
if let value = field.primitiveValue {
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
let title = object.$title.value
|
||||||
|
let name = object.$name.value
|
||||||
|
let value = "\(title) \(name)"
|
||||||
|
field.primitiveValue = value
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func keyPathsAffectingDisplayName() -> Set<String> {
|
||||||
|
|
||||||
|
return [
|
||||||
|
String(keyPath: \Person.$title),
|
||||||
|
String(keyPath: \Person.$name)
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,78 +189,227 @@ class Person: CoreStoreObject {
|
|||||||
|
|
||||||
class DynamicModelTests: BaseTestDataTestCase {
|
class DynamicModelTests: BaseTestDataTestCase {
|
||||||
|
|
||||||
func testDynamicModels_CanBeDeclaredCorrectly() {
|
@objc
|
||||||
|
dynamic func test_ThatDynamicModels_CanBeDeclaredCorrectly() {
|
||||||
|
|
||||||
let dataStack = DataStack(
|
let dataStack = DataStack(
|
||||||
CoreStoreSchema(
|
CoreStoreSchema(
|
||||||
modelVersion: "V1",
|
modelVersion: "V1",
|
||||||
entities: [
|
entities: [
|
||||||
Entity<Animal>("Animal"),
|
Entity<Animal>("Animal"),
|
||||||
Entity<Dog>("Dog"),
|
Entity<Dog>("Dog", indexes: [[\Dog.$nickname, \Dog.$age]]),
|
||||||
Entity<Person>("Person")
|
Entity<Person>("Person")
|
||||||
],
|
],
|
||||||
versionLock: [
|
versionLock: [
|
||||||
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||||
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
"Dog": [0xad6de93adc5565d, 0x7897e51253eba5a3, 0xd12b9ce0b13600f3, 0x5a4827cd794cd15e],
|
||||||
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
|
"Person": [0xf3e6ba6016bbedc6, 0x50dedf64f0eba490, 0xa32088a0ee83468d, 0xb72d1d0b37bd0992]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.prepareStack(dataStack, configurations: [nil]) { (stack) in
|
self.prepareStack(dataStack, configurations: [nil]) { (stack) in
|
||||||
|
|
||||||
let k1 = Animal.keyPath({ $0.species })
|
let k1 = String(keyPath: \Animal.$species)
|
||||||
XCTAssertEqual(k1, "species")
|
XCTAssertEqual(k1, "species")
|
||||||
|
|
||||||
let k2 = Dog.keyPath({ $0.species })
|
let k2 = String(keyPath: \Dog.$species)
|
||||||
XCTAssertEqual(k2, "species")
|
XCTAssertEqual(k2, "species")
|
||||||
|
|
||||||
let k3 = Dog.keyPath({ $0.nickname })
|
let k3 = String(keyPath: \Dog.$nickname)
|
||||||
XCTAssertEqual(k3, "nickname")
|
XCTAssertEqual(k3, "nickname")
|
||||||
|
|
||||||
let updateDone = self.expectation(description: "update-done")
|
let updateDone = self.expectation(description: "update-done")
|
||||||
let fetchDone = self.expectation(description: "fetch-done")
|
let fetchDone = self.expectation(description: "fetch-done")
|
||||||
|
let willSetPriorObserverDone = self.expectation(description: "willSet-observe-prior-done")
|
||||||
|
let willSetNotPriorObserverDone = self.expectation(description: "willSet-observe-notPrior-done")
|
||||||
|
let didSetObserverDone = self.expectation(description: "didSet-observe-done")
|
||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) in
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let animal = transaction.create(Into<Animal>())
|
let animal = transaction.create(Into<Animal>())
|
||||||
XCTAssertEqual(animal.species.value, "Swift")
|
XCTAssertEqual(animal.species, "Swift")
|
||||||
XCTAssertTrue(type(of: animal.species.value) == String.self)
|
XCTAssertTrue(type(of: animal.species) == String.self)
|
||||||
|
XCTAssertEqual(animal.color, Color.blue)
|
||||||
|
|
||||||
animal.species .= "Sparrow"
|
animal.species = "Sparrow"
|
||||||
XCTAssertEqual(animal.species.value, "Sparrow")
|
XCTAssertEqual(animal.species, "Sparrow")
|
||||||
|
|
||||||
animal.color .= .yellow
|
animal.color = .yellow
|
||||||
XCTAssertEqual(animal.color.value, UIColor.yellow)
|
XCTAssertEqual(animal.color, Color.yellow)
|
||||||
|
|
||||||
|
for property in Animal.metaProperties(includeSuperclasses: true) {
|
||||||
|
|
||||||
|
switch property.keyPath {
|
||||||
|
|
||||||
|
case String(keyPath: \Animal.$species):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Stored<String>)
|
||||||
|
|
||||||
|
case String(keyPath: \Animal.$master):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Relationship<Person?>)
|
||||||
|
|
||||||
|
case String(keyPath: \Animal.$color):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Coded<Color?>)
|
||||||
|
|
||||||
|
default:
|
||||||
|
XCTFail("Unknown KeyPath: \"\(property.keyPath)\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let dog = transaction.create(Into<Dog>())
|
let dog = transaction.create(Into<Dog>())
|
||||||
XCTAssertEqual(dog.species.value, "Swift")
|
XCTAssertEqual(dog.species, "Swift")
|
||||||
XCTAssertEqual(dog.nickname.value, nil)
|
XCTAssertEqual(dog.age, 1)
|
||||||
XCTAssertEqual(dog.age.value, 1)
|
XCTAssertTrue(Dog.commonNicknames.contains(dog.nickname))
|
||||||
|
|
||||||
|
for property in Dog.metaProperties(includeSuperclasses: true) {
|
||||||
|
|
||||||
|
switch property.keyPath {
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$species):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Stored<String>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$master):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Relationship<Person?>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$color):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Animal>.Coded<Color?>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$nickname):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Dog>.Stored<String>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$age):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Dog>.Stored<Int>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$friends):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Dog>.Relationship<[Dog]>)
|
||||||
|
|
||||||
|
case String(keyPath: \Dog.$friendedBy):
|
||||||
|
XCTAssertTrue(property is FieldContainer<Dog>.Relationship<Set<Dog>>)
|
||||||
|
|
||||||
|
default:
|
||||||
|
XCTFail("Unknown KeyPath: \"\(property.keyPath)\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let didSetObserver = dog.observe(\.$species, options: [.new, .old]) { (object, change) in
|
||||||
|
|
||||||
|
XCTAssertEqual(object, dog)
|
||||||
|
XCTAssertEqual(change.kind, .setting)
|
||||||
|
XCTAssertEqual(change.newValue, "Dog")
|
||||||
|
XCTAssertEqual(change.oldValue, "Swift")
|
||||||
|
XCTAssertFalse(change.isPrior)
|
||||||
|
XCTAssertEqual(object.species, "Dog")
|
||||||
|
didSetObserverDone.fulfill()
|
||||||
|
}
|
||||||
|
let willSetObserver = dog.observe(\.$species, options: [.new, .old, .prior]) { (object, change) in
|
||||||
|
|
||||||
|
XCTAssertEqual(object, dog)
|
||||||
|
XCTAssertEqual(change.kind, .setting)
|
||||||
|
XCTAssertEqual(change.oldValue, "Swift")
|
||||||
|
|
||||||
|
if change.isPrior {
|
||||||
|
|
||||||
|
XCTAssertNil(change.newValue)
|
||||||
|
XCTAssertEqual(object.species, "Swift")
|
||||||
|
willSetPriorObserverDone.fulfill()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
XCTAssertEqual(change.newValue, "Dog")
|
||||||
|
XCTAssertEqual(object.species, "Dog")
|
||||||
|
willSetNotPriorObserverDone.fulfill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dog.species .= "Dog"
|
dog.species = "Dog"
|
||||||
XCTAssertEqual(dog.species.value, "Dog")
|
XCTAssertEqual(dog.species, "Dog")
|
||||||
|
|
||||||
|
didSetObserver.invalidate()
|
||||||
|
willSetObserver.invalidate()
|
||||||
|
|
||||||
dog.nickname .= "Spot"
|
dog.nickname = "Spot"
|
||||||
XCTAssertEqual(dog.nickname.value, "Spot")
|
XCTAssertEqual(dog.nickname, "Spot")
|
||||||
|
|
||||||
let person = transaction.create(Into<Person>())
|
let person = transaction.create(Into<Person>())
|
||||||
XCTAssertTrue(person.pets.value.isEmpty)
|
XCTAssertTrue(person.pets.isEmpty)
|
||||||
|
XCTAssertEqual(person.customField.string, "customString")
|
||||||
|
let initialJob = person.job
|
||||||
|
XCTAssertTrue(Job.allCases.contains(initialJob))
|
||||||
|
|
||||||
person.name .= "John"
|
XCTAssertEqual(
|
||||||
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter
|
person.rawObject!
|
||||||
|
.runtimeType()
|
||||||
|
.keyPathsForValuesAffectingValue(forKey: "displayName"),
|
||||||
|
["title", "name"]
|
||||||
|
)
|
||||||
|
|
||||||
person.title .= "Sir"
|
person.name = "Joe"
|
||||||
XCTAssertEqual(person.name.value, "Sir John")
|
|
||||||
|
|
||||||
person.pets.value.insert(dog)
|
XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
|
||||||
|
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
|
||||||
|
|
||||||
|
person.rawObject!.setValue("AAAA", forKey: "displayName")
|
||||||
|
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
|
||||||
|
|
||||||
|
person.name = "John"
|
||||||
|
XCTAssertEqual(person.name, "John")
|
||||||
|
XCTAssertEqual(person.displayName, "Mr. John") // Custom getter
|
||||||
|
|
||||||
|
let personSnapshot1 = person.asSnapshot(in: transaction)!
|
||||||
|
XCTAssertEqual(person.name, personSnapshot1.$name)
|
||||||
|
XCTAssertEqual(person.title, personSnapshot1.$title)
|
||||||
|
XCTAssertEqual(person.displayName, personSnapshot1.$displayName)
|
||||||
|
XCTAssertEqual(person.job, personSnapshot1.$job)
|
||||||
|
|
||||||
|
person.title = "Sir"
|
||||||
|
XCTAssertEqual(person.displayName, "Sir John")
|
||||||
|
|
||||||
|
XCTAssertEqual(personSnapshot1.$name, "John")
|
||||||
|
XCTAssertEqual(personSnapshot1.$title, "Mr.")
|
||||||
|
XCTAssertEqual(personSnapshot1.$displayName, "Mr. John")
|
||||||
|
|
||||||
|
person.customField.string = "newCustomString"
|
||||||
|
XCTAssertEqual(person.customField.string, "newCustomString")
|
||||||
|
|
||||||
|
person.job = .engineer
|
||||||
|
XCTAssertEqual(person.job, .engineer)
|
||||||
|
|
||||||
|
let personSnapshot2 = person.asSnapshot(in: transaction)!
|
||||||
|
XCTAssertEqual(person.name, personSnapshot2.$name)
|
||||||
|
XCTAssertEqual(person.title, personSnapshot2.$title)
|
||||||
|
XCTAssertEqual(person.displayName, personSnapshot2.$displayName)
|
||||||
|
XCTAssertEqual(person.job, personSnapshot2.$job)
|
||||||
|
|
||||||
|
var personSnapshot3 = personSnapshot2
|
||||||
|
personSnapshot3.$name = "James"
|
||||||
|
XCTAssertEqual(personSnapshot1.$name, "John")
|
||||||
|
XCTAssertEqual(personSnapshot1.$displayName, "Mr. John")
|
||||||
|
XCTAssertEqual(personSnapshot1.$job, initialJob)
|
||||||
|
XCTAssertEqual(personSnapshot2.$name, "John")
|
||||||
|
XCTAssertEqual(personSnapshot2.$displayName, "Sir John")
|
||||||
|
XCTAssertEqual(personSnapshot2.$job, .engineer)
|
||||||
|
XCTAssertEqual(personSnapshot3.$name, "James")
|
||||||
|
XCTAssertEqual(personSnapshot3.$displayName, "Sir John")
|
||||||
|
XCTAssertEqual(personSnapshot3.$job, .engineer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
person.pets.insert(dog)
|
||||||
XCTAssertEqual(person.pets.count, 1)
|
XCTAssertEqual(person.pets.count, 1)
|
||||||
XCTAssertEqual(person.pets.value.first, dog)
|
XCTAssertEqual(person.pets.first, dog)
|
||||||
XCTAssertEqual(person.pets.value.first?.master.value, person)
|
XCTAssertEqual(person.pets.first?.master, person)
|
||||||
XCTAssertEqual(dog.master.value, person)
|
XCTAssertEqual(dog.master, person)
|
||||||
XCTAssertEqual(dog.master.value?.pets.value.first, dog)
|
XCTAssertEqual(dog.master?.pets.first, dog)
|
||||||
},
|
},
|
||||||
success: {
|
success: { _ in
|
||||||
|
|
||||||
|
let person = try! stack.fetchOne(From<Person>())
|
||||||
|
XCTAssertNotNil(person)
|
||||||
|
|
||||||
|
let personPublisher = person!.asPublisher(in: stack)
|
||||||
|
XCTAssertEqual(personPublisher.$name, "John")
|
||||||
|
XCTAssertEqual(personPublisher.$displayName, "Sir John")
|
||||||
|
XCTAssertEqual(personPublisher.$job, .engineer)
|
||||||
|
|
||||||
updateDone.fulfill()
|
updateDone.fulfill()
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
@@ -143,40 +420,92 @@ class DynamicModelTests: BaseTestDataTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) in
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let p1 = Animal.where({ $0.species == "Sparrow" })
|
let p1 = Where<Animal>({ $0.$species == "Sparrow" })
|
||||||
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
|
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
|
||||||
|
|
||||||
let bird = transaction.fetchOne(From<Animal>(), p1)
|
let bird = try transaction.fetchOne(From<Animal>(), p1)
|
||||||
XCTAssertNotNil(bird)
|
XCTAssertNotNil(bird)
|
||||||
XCTAssertEqual(bird!.species.value, "Sparrow")
|
XCTAssertEqual(bird!.species, "Sparrow")
|
||||||
|
XCTAssertEqual(bird!.color, Color.yellow)
|
||||||
|
|
||||||
let p2 = Dog.where({ $0.nickname == "Spot" })
|
let p2 = Where<Dog>({ $0.$nickname == "Spot" })
|
||||||
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
|
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
|
||||||
|
|
||||||
let dog = transaction.fetchOne(From<Dog>(), p2)
|
let dog = try transaction.fetchOne(From<Dog>().where(\.$nickname == "Spot"))
|
||||||
XCTAssertNotNil(dog)
|
XCTAssertNotNil(dog)
|
||||||
XCTAssertEqual(dog!.nickname.value, "Spot")
|
XCTAssertEqual(dog!.nickname, "Spot")
|
||||||
XCTAssertEqual(dog!.species.value, "Dog")
|
XCTAssertEqual(dog!.species, "Dog")
|
||||||
|
|
||||||
let person = transaction.fetchOne(From<Person>())
|
let person = try transaction.fetchOne(From<Person>())
|
||||||
XCTAssertNotNil(person)
|
XCTAssertNotNil(person)
|
||||||
XCTAssertEqual(person!.pets.value.first, dog)
|
XCTAssertEqual(person!.name, "John")
|
||||||
|
XCTAssertEqual(person!.title, "Sir")
|
||||||
|
XCTAssertEqual(person!.displayName, "Sir John")
|
||||||
|
XCTAssertEqual(person!.customField.string, "customString")
|
||||||
|
XCTAssertEqual(person!.job, .engineer)
|
||||||
|
XCTAssertEqual(person!.pets.first, dog)
|
||||||
|
|
||||||
let p3 = Dog.where({ $0.age == 10 })
|
let p3 = Where<Dog>({ $0.$age == 10 })
|
||||||
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
|
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
|
||||||
|
|
||||||
|
let totalAge = try transaction.queryValue(
|
||||||
|
From<Dog>().select(Int.self, .sum(\.$age))
|
||||||
|
)
|
||||||
|
XCTAssertEqual(totalAge, 1)
|
||||||
|
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>()
|
||||||
|
.where(\Animal.$species == "Dog" && \Dog.$age == 10)
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>()
|
||||||
|
.where(\Dog.$age == 10 && \Animal.$species == "Dog")
|
||||||
|
.orderBy(.ascending({ $0.$species }))
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>(),
|
||||||
|
Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>(),
|
||||||
|
Where<Dog>({ $0.$species == "Dog" && $0.$age == 10 })
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>(),
|
||||||
|
Where<Dog>({ $0.$age == 10 && $0.$species == "Dog" })
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>(),
|
||||||
|
Where<Dog>({ $0.$age > 10 && $0.$age <= 15 })
|
||||||
|
)
|
||||||
|
_ = try transaction.fetchAll(
|
||||||
|
From<Dog>(),
|
||||||
|
(\Dog.$age > 10 && \Dog.$age <= 15)
|
||||||
|
)
|
||||||
},
|
},
|
||||||
success: {
|
success: { _ in
|
||||||
|
|
||||||
fetchDone.fulfill()
|
fetchDone.fulfill()
|
||||||
withExtendedLifetime(stack, {})
|
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.waitAndCheckExpectations()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.waitForExpectations(timeout: 10, handler: { _ in })
|
||||||
|
|
||||||
|
self.addTeardownBlock {
|
||||||
|
dataStack.unsafeRemoveAllPersistentStoresAndWait()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
|
||||||
|
|
||||||
|
XCTAssertEqual(String(keyPath: \Animal.$species), "species")
|
||||||
|
XCTAssertEqual(String(keyPath: \Dog.$species), "species")
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
@@ -190,7 +519,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
|||||||
SQLiteStore(
|
SQLiteStore(
|
||||||
fileURL: SQLiteStore.defaultRootDirectory
|
fileURL: SQLiteStore.defaultRootDirectory
|
||||||
.appendingPathComponent(UUID().uuidString)
|
.appendingPathComponent(UUID().uuidString)
|
||||||
.appendingPathComponent("\(type(of: self))_\((configuration ?? "-null-")).sqlite"),
|
.appendingPathComponent("\(Self.self)_\((configuration ?? "-null-")).sqlite"),
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// ErrorTests.swift
|
// ErrorTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -42,14 +42,12 @@ final class ErrorTests: XCTestCase {
|
|||||||
|
|
||||||
let userInfo: NSDictionary = [:]
|
let userInfo: NSDictionary = [:]
|
||||||
|
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error as NSError
|
||||||
XCTAssertEqual(error, objcError.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue)
|
XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue)
|
||||||
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
||||||
|
|
||||||
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
|
let objcError2 = CoreStoreError(objcError) as NSError
|
||||||
XCTAssertEqual(error, objcError2.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue)
|
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue)
|
||||||
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
||||||
@@ -67,14 +65,12 @@ final class ErrorTests: XCTestCase {
|
|||||||
let userInfo: NSDictionary = [
|
let userInfo: NSDictionary = [
|
||||||
"existingPersistentStoreURL": dummyURL
|
"existingPersistentStoreURL": dummyURL
|
||||||
]
|
]
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error as NSError
|
||||||
XCTAssertEqual(error, objcError.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
|
XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
|
||||||
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
||||||
|
|
||||||
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
|
let objcError2 = CoreStoreError(objcError) as NSError
|
||||||
XCTAssertEqual(error, objcError2.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
|
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue)
|
||||||
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
||||||
@@ -86,8 +82,10 @@ final class ErrorTests: XCTestCase {
|
|||||||
let dummyURL = URL(string: "file:///test1/test2.sqlite")!
|
let dummyURL = URL(string: "file:///test1/test2.sqlite")!
|
||||||
|
|
||||||
let schemaHistory = SchemaHistory(
|
let schemaHistory = SchemaHistory(
|
||||||
modelName: "Model",
|
XcodeDataModelSchema.from(
|
||||||
bundle: Bundle(for: type(of: self))
|
modelName: "Model",
|
||||||
|
bundle: Bundle.module
|
||||||
|
)
|
||||||
)
|
)
|
||||||
let version = "1.0.0"
|
let version = "1.0.0"
|
||||||
|
|
||||||
@@ -100,14 +98,12 @@ final class ErrorTests: XCTestCase {
|
|||||||
"targetModel": schemaHistory.rawModel,
|
"targetModel": schemaHistory.rawModel,
|
||||||
"targetModelVersion": version
|
"targetModelVersion": version
|
||||||
]
|
]
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error as NSError
|
||||||
XCTAssertEqual(error, objcError.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
||||||
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
||||||
|
|
||||||
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
|
let objcError2 = CoreStoreError(objcError) as NSError
|
||||||
XCTAssertEqual(error, objcError2.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
||||||
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
||||||
@@ -125,14 +121,12 @@ final class ErrorTests: XCTestCase {
|
|||||||
let userInfo: NSDictionary = [
|
let userInfo: NSDictionary = [
|
||||||
"localStoreURL": dummyURL
|
"localStoreURL": dummyURL
|
||||||
]
|
]
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error as NSError
|
||||||
XCTAssertEqual(error, objcError.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
|
XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
|
||||||
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
||||||
|
|
||||||
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
|
let objcError2 = CoreStoreError(objcError) as NSError
|
||||||
XCTAssertEqual(error, objcError2.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
|
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue)
|
||||||
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
||||||
@@ -157,14 +151,12 @@ final class ErrorTests: XCTestCase {
|
|||||||
let userInfo: NSDictionary = [
|
let userInfo: NSDictionary = [
|
||||||
"NSError": internalError
|
"NSError": internalError
|
||||||
]
|
]
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error as NSError
|
||||||
XCTAssertEqual(error, objcError.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue)
|
XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue)
|
||||||
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo)
|
||||||
|
|
||||||
let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC
|
let objcError2 = CoreStoreError(objcError) as NSError
|
||||||
XCTAssertEqual(error, objcError2.bridgeToSwift)
|
|
||||||
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue)
|
XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue)
|
||||||
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// GroupByTests.swift
|
// GroupByTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -38,14 +39,14 @@ final class GroupByTests: BaseTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let groupBy = GroupBy()
|
let groupBy = GroupBy<NSManagedObject>()
|
||||||
XCTAssertEqual(groupBy, GroupBy([] as [String]))
|
XCTAssertEqual(groupBy, GroupBy([] as [String]))
|
||||||
XCTAssertNotEqual(groupBy, GroupBy("key"))
|
XCTAssertNotEqual(groupBy, GroupBy("key"))
|
||||||
XCTAssertTrue(groupBy.keyPaths.isEmpty)
|
XCTAssertTrue(groupBy.keyPaths.isEmpty)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let groupBy = GroupBy("key1")
|
let groupBy = GroupBy<NSManagedObject>("key1")
|
||||||
XCTAssertEqual(groupBy, GroupBy("key1"))
|
XCTAssertEqual(groupBy, GroupBy("key1"))
|
||||||
XCTAssertEqual(groupBy, GroupBy(["key1"]))
|
XCTAssertEqual(groupBy, GroupBy(["key1"]))
|
||||||
XCTAssertNotEqual(groupBy, GroupBy("key2"))
|
XCTAssertNotEqual(groupBy, GroupBy("key2"))
|
||||||
@@ -53,7 +54,7 @@ final class GroupByTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let groupBy = GroupBy("key1", "key2")
|
let groupBy = GroupBy<NSManagedObject>("key1", "key2")
|
||||||
XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
|
XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
|
||||||
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
|
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
|
||||||
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
|
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
|
||||||
@@ -66,10 +67,10 @@ final class GroupByTests: BaseTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (dataStack) in
|
self.prepareStack { (dataStack) in
|
||||||
|
|
||||||
let groupBy = GroupBy(#keyPath(TestEntity1.testString))
|
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
|
||||||
|
|
||||||
let request = CoreStoreFetchRequest()
|
let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||||
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
|
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
|
||||||
groupBy.applyToFetchRequest(request)
|
groupBy.applyToFetchRequest(request)
|
||||||
|
|
||||||
XCTAssertNotNil(request.propertiesToGroupBy)
|
XCTAssertNotNil(request.propertiesToGroupBy)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// ImportTests.swift
|
// ImportTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,33 +36,33 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
|
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
|
||||||
|
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: true))?.boolValue, true)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: true))?.boolValue, true)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
||||||
|
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||||
|
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||||
|
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: true)))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: true)))
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max)))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max)))
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max)))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max)))
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max)))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max)))
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT)))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT)))
|
||||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
||||||
|
|
||||||
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
|
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
|
||||||
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
|
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
|
||||||
@@ -95,7 +95,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +137,9 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestInsertError {
|
catch _ as TestInsertError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = try transaction.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertNil(object?.testEntityID)
|
XCTAssertNil(object?.testEntityID)
|
||||||
XCTAssertNil(object?.testBoolean)
|
XCTAssertNil(object?.testBoolean)
|
||||||
@@ -182,7 +182,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
XCTAssertNil(object?.testEntityID)
|
XCTAssertNil(object?.testEntityID)
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
|
||||||
@@ -202,7 +202,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
#keyPath(TestEntity1.testDate): self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!
|
#keyPath(TestEntity1.testDate): self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
XCTAssertNil(object?.testEntityID)
|
XCTAssertNil(object?.testEntityID)
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 2))
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 2))
|
||||||
@@ -254,7 +254,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
sourceArray: sourceArray
|
sourceArray: sourceArray
|
||||||
)
|
)
|
||||||
XCTAssertEqual(objects.count, 1)
|
XCTAssertEqual(objects.count, 1)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = objects[0]
|
let object = objects[0]
|
||||||
let dictionary = sourceArray[1]
|
let dictionary = sourceArray[1]
|
||||||
@@ -316,9 +316,9 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestInsertError {
|
catch _ as TestInsertError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = try transaction.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertNil(object?.testEntityID)
|
XCTAssertNil(object?.testEntityID)
|
||||||
XCTAssertNil(object?.testBoolean)
|
XCTAssertNil(object?.testBoolean)
|
||||||
@@ -372,7 +372,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
sourceArray: sourceArray
|
sourceArray: sourceArray
|
||||||
)
|
)
|
||||||
XCTAssertEqual(objects.count, sourceArray.count)
|
XCTAssertEqual(objects.count, sourceArray.count)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 2)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 2)
|
||||||
|
|
||||||
for i in 0 ..< sourceArray.count {
|
for i in 0 ..< sourceArray.count {
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -442,20 +442,19 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
|
||||||
|
|
||||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||||
XCTAssertNotNil(existingObjects)
|
XCTAssertEqual(existingObjects.count, 1)
|
||||||
XCTAssertEqual(existingObjects?.count, 1)
|
|
||||||
|
|
||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects[0]
|
||||||
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105))
|
XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
|
||||||
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
|
||||||
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5))
|
XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
|
||||||
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
|
XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
|
||||||
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
|
XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
|
||||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -504,7 +503,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
XCTAssertEqual(objects.count, 1)
|
XCTAssertEqual(objects.count, 1)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
let object = objects[0]
|
let object = objects[0]
|
||||||
let dictionary = sourceArray[1]
|
let dictionary = sourceArray[1]
|
||||||
@@ -565,7 +564,9 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(objects.count, 2)
|
XCTAssertEqual(objects.count, 2)
|
||||||
|
|
||||||
zip(objects, sourceArray)
|
zip(objects, sourceArray)
|
||||||
.forEach { object, dictionary in
|
.forEach {
|
||||||
|
|
||||||
|
let (object, dictionary) = $0
|
||||||
XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber)
|
XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber)
|
||||||
XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber)
|
XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber)
|
||||||
XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber)
|
XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber)
|
||||||
@@ -616,9 +617,9 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestInsertError {
|
catch _ as TestInsertError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||||
XCTAssertNil(object?.testBoolean)
|
XCTAssertNil(object?.testBoolean)
|
||||||
@@ -655,21 +656,19 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestUpdateError {
|
catch _ as TestUpdateError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||||
XCTAssertNotNil(existingObjects)
|
XCTAssertEqual(existingObjects.count, 1)
|
||||||
XCTAssertEqual(existingObjects?.count, 1)
|
|
||||||
|
|
||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects[0]
|
||||||
XCTAssertNotNil(existingObject)
|
XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
|
||||||
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105))
|
XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
|
||||||
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
|
||||||
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5))
|
XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
|
||||||
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
|
XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
|
||||||
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
|
XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
}
|
}
|
||||||
@@ -708,7 +707,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -733,7 +732,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||||
@@ -743,11 +742,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!)
|
||||||
|
|
||||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||||
XCTAssertNotNil(existingObjects)
|
XCTAssertEqual(existingObjects.count, 1)
|
||||||
XCTAssertEqual(existingObjects?.count, 1)
|
|
||||||
|
|
||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects[0]
|
||||||
XCTAssertEqual(existingObject, object)
|
XCTAssertEqual(existingObject, object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -797,7 +795,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
sourceArray: sourceArray
|
sourceArray: sourceArray
|
||||||
)
|
)
|
||||||
XCTAssertEqual(objects.count, 1)
|
XCTAssertEqual(objects.count, 1)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
|
|
||||||
let object = objects[0]
|
let object = objects[0]
|
||||||
let dictionary = sourceArray[1]
|
let dictionary = sourceArray[1]
|
||||||
@@ -862,10 +860,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestIDError {
|
catch _ as TestIDError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
|
||||||
|
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
||||||
}
|
}
|
||||||
transaction.unsafeContext().reset()
|
transaction.unsafeContext().reset()
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
@@ -908,7 +906,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||||
XCTAssertNil(object?.testBoolean)
|
XCTAssertNil(object?.testBoolean)
|
||||||
@@ -949,9 +947,9 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
catch _ as TestUpdateError {
|
catch _ as TestUpdateError {
|
||||||
|
|
||||||
errorExpectation.fulfill()
|
errorExpectation.fulfill()
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 105))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 105))
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -961,11 +959,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||||
|
|
||||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||||
XCTAssertNotNil(existingObjects)
|
XCTAssertEqual(existingObjects.count, 1)
|
||||||
XCTAssertEqual(existingObjects?.count, 1)
|
|
||||||
|
|
||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects[0]
|
||||||
XCTAssertEqual(existingObject, object)
|
XCTAssertEqual(existingObject, object)
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
transaction.context.reset()
|
||||||
@@ -1016,7 +1013,7 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
sourceArray: sourceArray
|
sourceArray: sourceArray
|
||||||
)
|
)
|
||||||
XCTAssertEqual(objects.count, sourceArray.count)
|
XCTAssertEqual(objects.count, sourceArray.count)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
|
||||||
for i in 0 ..< sourceArray.count {
|
for i in 0 ..< sourceArray.count {
|
||||||
|
|
||||||
let object = objects[i]
|
let object = objects[i]
|
||||||
@@ -1030,11 +1027,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||||
XCTAssertNotNil(existingObjects)
|
XCTAssertEqual(existingObjects.count, 1)
|
||||||
XCTAssertEqual(existingObjects?.count, 1)
|
|
||||||
|
|
||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects[0]
|
||||||
XCTAssertEqual(existingObject, objects[0])
|
XCTAssertEqual(existingObject, objects[0])
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// ListObserverTests.swift
|
// ListObserverTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -31,7 +32,6 @@ import CoreStore
|
|||||||
|
|
||||||
// MARK: - ListObserverTests
|
// MARK: - ListObserverTests
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
class ListObserverTests: BaseTestDataTestCase {
|
class ListObserverTests: BaseTestDataTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -43,7 +43,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
let monitor = stack.monitorSectionedList(
|
let monitor = stack.monitorSectionedList(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||||
)
|
)
|
||||||
monitor.addObserver(observer)
|
monitor.addObserver(observer)
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let willChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorWillChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -67,8 +67,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didInsertSectionExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitor:didInsertSection:toSectionIndex:",
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertSection:toSectionIndex:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
((note.userInfo as NSDictionary?) ?? [:]),
|
((note.userInfo as NSDictionary?) ?? [:]),
|
||||||
[
|
[
|
||||||
"sectionInfo": monitor.sectionInfoAtIndex(0),
|
"sectionInfo": monitor.sectionInfo(at: 0),
|
||||||
"sectionIndex": 0
|
"sectionIndex": 0
|
||||||
] as NSDictionary
|
] as NSDictionary
|
||||||
)
|
)
|
||||||
@@ -87,8 +87,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 1
|
return events == 1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didInsertObjectExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitor:didInsertObject:toIndexPath:",
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -101,9 +101,9 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
["indexPath", "object"]
|
["indexPath", "object"]
|
||||||
)
|
)
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
XCTAssertEqual(indexPath?.section, 0)
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
XCTAssertEqual(indexPath?.item, 0)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -119,8 +119,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 2
|
return events == 2
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorDidChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -171,21 +171,21 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
let monitor = stack.monitorSectionedList(
|
let monitor = stack.monitorSectionedList(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||||
)
|
)
|
||||||
monitor.addObserver(observer)
|
monitor.addObserver(observer)
|
||||||
|
|
||||||
XCTAssertTrue(monitor.hasSections())
|
XCTAssertTrue(monitor.hasSections())
|
||||||
XCTAssertEqual(monitor.numberOfSections(), 2)
|
XCTAssertEqual(monitor.numberOfSections(), 2)
|
||||||
XCTAssertTrue(monitor.hasObjects())
|
XCTAssertTrue(monitor.hasObjects())
|
||||||
XCTAssertTrue(monitor.hasObjectsInSection(0))
|
XCTAssertTrue(monitor.hasObjects(in: 0))
|
||||||
XCTAssertEqual(monitor.numberOfObjectsInSection(0), 2)
|
XCTAssertEqual(monitor.numberOfObjects(in: 0), 2)
|
||||||
XCTAssertEqual(monitor.numberOfObjectsInSection(1), 3)
|
XCTAssertEqual(monitor.numberOfObjects(in: 1), 3)
|
||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let willChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorWillChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -198,62 +198,60 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
for _ in 1 ... 2 {
|
|
||||||
|
_ = self.expectation(
|
||||||
let didUpdateObjectExpectation = self.expectation(
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
|
||||||
forNotification: "listMonitor:didUpdateObject:atIndexPath:",
|
object: observer,
|
||||||
object: observer,
|
handler: { (note) -> Bool in
|
||||||
handler: { (note) -> Bool in
|
|
||||||
|
XCTAssert(events == 1 || events == 2)
|
||||||
|
|
||||||
|
let userInfo = note.userInfo
|
||||||
|
XCTAssertNotNil(userInfo)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||||
|
["indexPath", "object"]
|
||||||
|
)
|
||||||
|
|
||||||
|
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||||
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
|
|
||||||
|
switch object?.testEntityID {
|
||||||
|
|
||||||
XCTAssert(events == 1 || events == 2)
|
case NSNumber(value: 101)?:
|
||||||
|
XCTAssertEqual(indexPath?.section, 1)
|
||||||
|
XCTAssertEqual(indexPath?.item, 0)
|
||||||
|
|
||||||
let userInfo = note.userInfo
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
XCTAssertNotNil(userInfo)
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||||
["indexPath", "object"]
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
case NSNumber(value: 102)?:
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
XCTAssertEqual(indexPath?.section, 0)
|
||||||
|
XCTAssertEqual(indexPath?.item, 0)
|
||||||
|
|
||||||
switch object?.testEntityID {
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||||
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||||
case NSNumber(value: 101)?:
|
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
default:
|
||||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
XCTFail()
|
||||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
|
||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
|
||||||
|
|
||||||
case NSNumber(value: 102)?:
|
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
|
||||||
|
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
|
||||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
|
||||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
|
||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
defer {
|
|
||||||
|
|
||||||
events += 1
|
|
||||||
}
|
|
||||||
return events == 1 || events == 2
|
|
||||||
}
|
}
|
||||||
)
|
defer {
|
||||||
}
|
|
||||||
let didChangeExpectation = self.expectation(
|
events += 1
|
||||||
forNotification: "listMonitorDidChange:",
|
}
|
||||||
|
return events == 1 || events == 2
|
||||||
|
}
|
||||||
|
)
|
||||||
|
_ = self.expectation(
|
||||||
|
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -270,9 +268,9 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
if let object = transaction.fetchOne(
|
if let object = try transaction.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
|
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
|
||||||
|
|
||||||
object.testNumber = NSNumber(value: 11)
|
object.testNumber = NSNumber(value: 11)
|
||||||
object.testDecimal = NSDecimalNumber(string: "11")
|
object.testDecimal = NSDecimalNumber(string: "11")
|
||||||
@@ -284,9 +282,9 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
if let object = transaction.fetchOne(
|
if let object = try transaction.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||||
|
|
||||||
object.testNumber = NSNumber(value: 22)
|
object.testNumber = NSNumber(value: 22)
|
||||||
object.testDecimal = NSDecimalNumber(string: "22")
|
object.testDecimal = NSDecimalNumber(string: "22")
|
||||||
@@ -325,14 +323,14 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
let monitor = stack.monitorSectionedList(
|
let monitor = stack.monitorSectionedList(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||||
)
|
)
|
||||||
monitor.addObserver(observer)
|
monitor.addObserver(observer)
|
||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let willChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorWillChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -345,8 +343,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didMoveObjectExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:",
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -359,13 +357,13 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
["fromIndexPath", "toIndexPath", "object"]
|
["fromIndexPath", "toIndexPath", "object"]
|
||||||
)
|
)
|
||||||
|
|
||||||
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
|
let fromIndexPath = userInfo?["fromIndexPath"] as? IndexPath
|
||||||
XCTAssertEqual(fromIndexPath?.index(atPosition: 0), 0)
|
XCTAssertEqual(fromIndexPath?.section, 0)
|
||||||
XCTAssertEqual(fromIndexPath?.index(atPosition: 1), 0)
|
XCTAssertEqual(fromIndexPath?.item, 0)
|
||||||
|
|
||||||
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
|
let toIndexPath = userInfo?["toIndexPath"] as? IndexPath
|
||||||
XCTAssertEqual(toIndexPath?.index(atPosition: 0), 1)
|
XCTAssertEqual(toIndexPath?.section, 1)
|
||||||
XCTAssertEqual(toIndexPath?.index(atPosition: 1), 1)
|
XCTAssertEqual(toIndexPath?.item, 1)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
||||||
@@ -378,8 +376,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 1
|
return events == 1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorDidChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -396,9 +394,9 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
if let object = transaction.fetchOne(
|
if let object = try transaction.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||||
|
|
||||||
object.testBoolean = NSNumber(value: true)
|
object.testBoolean = NSNumber(value: true)
|
||||||
}
|
}
|
||||||
@@ -433,14 +431,14 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
let monitor = stack.monitorSectionedList(
|
let monitor = stack.monitorSectionedList(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||||
)
|
)
|
||||||
monitor.addObserver(observer)
|
monitor.addObserver(observer)
|
||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let willChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorWillChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -453,40 +451,37 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
for _ in 1 ... 2 {
|
_ = self.expectation(
|
||||||
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"),
|
||||||
let didUpdateObjectExpectation = self.expectation(
|
object: observer,
|
||||||
forNotification: "listMonitor:didDeleteObject:fromIndexPath:",
|
handler: { (note) -> Bool in
|
||||||
object: observer,
|
|
||||||
handler: { (note) -> Bool in
|
XCTAssert(events == 1 || events == 2)
|
||||||
|
|
||||||
|
let userInfo = note.userInfo
|
||||||
|
XCTAssertNotNil(userInfo)
|
||||||
|
XCTAssertEqual(
|
||||||
|
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||||
|
["indexPath", "object"]
|
||||||
|
)
|
||||||
|
|
||||||
|
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||||
|
|
||||||
|
XCTAssertEqual(indexPath?.section, 0)
|
||||||
|
XCTAssert(indexPath?.item == 0 || indexPath?.item == 1)
|
||||||
|
|
||||||
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
|
XCTAssertEqual(object?.isDeleted, true)
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
XCTAssert(events == 1 || events == 2)
|
events += 1
|
||||||
|
|
||||||
let userInfo = note.userInfo
|
|
||||||
XCTAssertNotNil(userInfo)
|
|
||||||
XCTAssertEqual(
|
|
||||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
|
||||||
["indexPath", "object"]
|
|
||||||
)
|
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
|
||||||
|
|
||||||
XCTAssertEqual(indexPath?.section, 0)
|
|
||||||
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
|
||||||
XCTAssertEqual(object?.isDeleted, true)
|
|
||||||
|
|
||||||
defer {
|
|
||||||
|
|
||||||
events += 1
|
|
||||||
}
|
|
||||||
return events == 1 || events == 2
|
|
||||||
}
|
}
|
||||||
)
|
return events == 1 || events == 2
|
||||||
}
|
}
|
||||||
let didDeleteSectionExpectation = self.expectation(
|
)
|
||||||
forNotification: "listMonitor:didDeleteSection:fromSectionIndex:",
|
_ = self.expectation(
|
||||||
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -513,8 +508,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 3
|
return events == 3
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorDidChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -531,10 +526,11 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
transaction.deleteAll(
|
let count = try transaction.deleteAll(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
||||||
)
|
)
|
||||||
|
XCTAssertEqual(count, 2)
|
||||||
return transaction.hasChanges
|
return transaction.hasChanges
|
||||||
},
|
},
|
||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
@@ -555,7 +551,6 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
// MARK: TestListObserver
|
// MARK: TestListObserver
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
class TestListObserver: ListSectionObserver {
|
class TestListObserver: ListSectionObserver {
|
||||||
|
|
||||||
// MARK: ListObserver
|
// MARK: ListObserver
|
||||||
|
|||||||
303
CoreStoreTests/ListPublisherTests.swift
Normal file
303
CoreStoreTests/ListPublisherTests.swift
Normal 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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// ObjectObserverTests.swift
|
// ObjectObserverTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -31,7 +31,6 @@ import CoreStore
|
|||||||
|
|
||||||
// MARK: - ObjectObserverTests
|
// MARK: - ObjectObserverTests
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
class ObjectObserverTests: BaseTestDataTestCase {
|
class ObjectObserverTests: BaseTestDataTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -41,9 +40,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
guard let object = stack.fetchOne(
|
guard let object = try stack.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -57,8 +56,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let willUpdateExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "objectMonitor:willUpdateObject:",
|
forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -74,8 +73,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didUpdateExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "objectMonitor:didUpdateObject:changedPersistentKeys:",
|
forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -138,9 +137,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
guard let object = stack.fetchOne(
|
guard let object = try stack.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -154,8 +153,8 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
|
|
||||||
let didDeleteExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "objectMonitor:didDeleteObject:",
|
forNotification: NSNotification.Name(rawValue: "objectMonitor:didDeleteObject:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -203,7 +202,6 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
// MARK: TestObjectObserver
|
// MARK: TestObjectObserver
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
class TestObjectObserver: ObjectObserver {
|
class TestObjectObserver: ObjectObserver {
|
||||||
|
|
||||||
typealias ObjectEntityType = TestEntity1
|
typealias ObjectEntityType = TestEntity1
|
||||||
@@ -219,7 +217,7 @@ class TestObjectObserver: ObjectObserver {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<KeyPath>) {
|
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<String>) {
|
||||||
|
|
||||||
NotificationCenter.default.post(
|
NotificationCenter.default.post(
|
||||||
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
||||||
|
|||||||
154
CoreStoreTests/ObjectPublisherTests.swift
Normal file
154
CoreStoreTests/ObjectPublisherTests.swift
Normal 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, {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// OrderByTests.swift
|
// OrderByTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -38,21 +39,21 @@ final class OrderByTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let orderBy = OrderBy()
|
let orderBy = OrderBy<NSManagedObject>()
|
||||||
XCTAssertEqual(orderBy, OrderBy([NSSortDescriptor]()))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([NSSortDescriptor]()))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key", ascending: false)))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key", ascending: false)))
|
||||||
XCTAssertTrue(orderBy.sortDescriptors.isEmpty)
|
XCTAssertTrue(orderBy.sortDescriptors.isEmpty)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
||||||
let orderBy = OrderBy(sortDescriptor)
|
let orderBy = OrderBy<NSManagedObject>(sortDescriptor)
|
||||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
|
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
|
||||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key1", ascending: false)))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key1", ascending: false)))
|
||||||
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
|
||||||
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
@@ -61,76 +62,76 @@ final class OrderByTests: XCTestCase {
|
|||||||
NSSortDescriptor(key: "key1", ascending: true),
|
NSSortDescriptor(key: "key1", ascending: true),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
let orderBy = OrderBy(sortDescriptors)
|
let orderBy = OrderBy<NSManagedObject>(sortDescriptors)
|
||||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||||
XCTAssertNotEqual(
|
XCTAssertNotEqual(
|
||||||
orderBy,
|
orderBy,
|
||||||
OrderBy(
|
OrderBy<NSManagedObject>(
|
||||||
[
|
[
|
||||||
NSSortDescriptor(key: "key1", ascending: false),
|
NSSortDescriptor(key: "key1", ascending: false),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let orderBy = OrderBy(.ascending("key1"))
|
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"))
|
||||||
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
||||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptor))
|
||||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
|
||||||
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
|
||||||
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let orderBy = OrderBy(.ascending("key1"), .descending("key2"))
|
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"))
|
||||||
let sortDescriptors = [
|
let sortDescriptors = [
|
||||||
NSSortDescriptor(key: "key1", ascending: true),
|
NSSortDescriptor(key: "key1", ascending: true),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||||
XCTAssertNotEqual(
|
XCTAssertNotEqual(
|
||||||
orderBy,
|
orderBy,
|
||||||
OrderBy(
|
OrderBy<NSManagedObject>(
|
||||||
[
|
[
|
||||||
NSSortDescriptor(key: "key1", ascending: false),
|
NSSortDescriptor(key: "key1", ascending: false),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sortKeys: [SortKey] = [.ascending("key1"), .descending("key2")]
|
let sortKeys: [OrderBy<NSManagedObject>.SortKey] = [.ascending("key1"), .descending("key2")]
|
||||||
let orderBy = OrderBy(sortKeys)
|
let orderBy = OrderBy<NSManagedObject>(sortKeys)
|
||||||
let sortDescriptors = [
|
let sortDescriptors = [
|
||||||
NSSortDescriptor(key: "key1", ascending: true),
|
NSSortDescriptor(key: "key1", ascending: true),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||||
XCTAssertNotEqual(
|
XCTAssertNotEqual(
|
||||||
orderBy,
|
orderBy,
|
||||||
OrderBy(
|
OrderBy<NSManagedObject>(
|
||||||
[
|
[
|
||||||
NSSortDescriptor(key: "key1", ascending: false),
|
NSSortDescriptor(key: "key1", ascending: false),
|
||||||
NSSortDescriptor(key: "key2", ascending: false)
|
NSSortDescriptor(key: "key2", ascending: false)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,15 +139,15 @@ final class OrderByTests: XCTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() {
|
dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() {
|
||||||
|
|
||||||
let orderBy1 = OrderBy(.ascending("key1"))
|
let orderBy1 = OrderBy<NSManagedObject>(.ascending("key1"))
|
||||||
let orderBy2 = OrderBy(.descending("key2"))
|
let orderBy2 = OrderBy<NSManagedObject>(.descending("key2"))
|
||||||
let orderBy3 = OrderBy(.ascending("key3"))
|
let orderBy3 = OrderBy<NSManagedObject>(.ascending("key3"))
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let plusOrderBy = orderBy1 + orderBy2 + orderBy3
|
let plusOrderBy = orderBy1 + orderBy2 + orderBy3
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2"), .ascending("key3")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2"), .ascending("key3")))
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
||||||
@@ -158,14 +159,14 @@ final class OrderByTests: XCTestCase {
|
|||||||
|
|
||||||
var plusOrderBy = orderBy1
|
var plusOrderBy = orderBy1
|
||||||
plusOrderBy += orderBy2
|
plusOrderBy += orderBy2
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2")))
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1)
|
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1)
|
||||||
XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors)
|
XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors)
|
||||||
|
|
||||||
plusOrderBy += orderBy3
|
plusOrderBy += orderBy3
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")) + OrderBy(.ascending("key3")))
|
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")) + OrderBy<NSManagedObject>(.ascending("key3")))
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
||||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
||||||
@@ -178,8 +179,8 @@ final class OrderByTests: XCTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
|
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
|
||||||
|
|
||||||
let orderBy = OrderBy(.ascending("key"))
|
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
|
||||||
let request = CoreStoreFetchRequest()
|
let request = Internals.CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||||
orderBy.applyToFetchRequest(request)
|
orderBy.applyToFetchRequest(request)
|
||||||
XCTAssertNotNil(request.sortDescriptors)
|
XCTAssertNotNil(request.sortDescriptors)
|
||||||
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)
|
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
// SectionByTests.swift
|
// SectionByTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -31,7 +32,6 @@ import CoreStore
|
|||||||
|
|
||||||
//MARK: - SectionByTests
|
//MARK: - SectionByTests
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
final class SectionByTests: XCTestCase {
|
final class SectionByTests: XCTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -39,13 +39,16 @@ final class SectionByTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sectionBy = SectionBy("key")
|
let sectionBy = SectionBy<NSManagedObject>("key")
|
||||||
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
||||||
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key")
|
XCTAssertNil(sectionBy.sectionIndexTransformer("key"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sectionBy = SectionBy("key") { $0.flatMap { "\($0):suffix" } }
|
let sectionBy = SectionBy<NSManagedObject>(
|
||||||
|
"key",
|
||||||
|
sectionIndexTransformer: { $0.flatMap { "\($0):suffix" } }
|
||||||
|
)
|
||||||
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
||||||
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
|
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
|
||||||
XCTAssertNil(sectionBy.sectionIndexTransformer(nil))
|
XCTAssertNil(sectionBy.sectionIndexTransformer(nil))
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// SelectTests.swift
|
// SelectTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -38,7 +39,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term: SelectTerm = "attribute"
|
let term: SelectTerm<NSManagedObject> = "attribute"
|
||||||
XCTAssertEqual(term, SelectTerm.attribute("attribute"))
|
XCTAssertEqual(term, SelectTerm.attribute("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
||||||
@@ -58,7 +59,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.attribute("attribute")
|
let term = SelectTerm<NSManagedObject>.attribute("attribute")
|
||||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.count("attribute"))
|
XCTAssertNotEqual(term, SelectTerm.count("attribute"))
|
||||||
@@ -82,7 +83,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.average("attribute")
|
let term = SelectTerm<NSManagedObject>.average("attribute")
|
||||||
XCTAssertEqual(term, SelectTerm.average("attribute"))
|
XCTAssertEqual(term, SelectTerm.average("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
||||||
@@ -106,7 +107,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.average("attribute", as: "alias")
|
let term = SelectTerm<NSManagedObject>.average("attribute", as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias"))
|
XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
||||||
@@ -135,7 +136,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.count("attribute")
|
let term = SelectTerm<NSManagedObject>.count("attribute")
|
||||||
XCTAssertEqual(term, SelectTerm.count("attribute"))
|
XCTAssertEqual(term, SelectTerm.count("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
||||||
@@ -159,7 +160,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.count("attribute", as: "alias")
|
let term = SelectTerm<NSManagedObject>.count("attribute", as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias"))
|
XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
||||||
@@ -188,7 +189,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.maximum("attribute")
|
let term = SelectTerm<NSManagedObject>.maximum("attribute")
|
||||||
XCTAssertEqual(term, SelectTerm.maximum("attribute"))
|
XCTAssertEqual(term, SelectTerm.maximum("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
||||||
@@ -212,7 +213,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.maximum("attribute", as: "alias")
|
let term = SelectTerm<NSManagedObject>.maximum("attribute", as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
||||||
@@ -241,7 +242,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.minimum("attribute")
|
let term = SelectTerm<NSManagedObject>.minimum("attribute")
|
||||||
XCTAssertEqual(term, SelectTerm.minimum("attribute"))
|
XCTAssertEqual(term, SelectTerm.minimum("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
||||||
@@ -265,7 +266,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.minimum("attribute", as: "alias")
|
let term = SelectTerm<NSManagedObject>.minimum("attribute", as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
||||||
@@ -294,7 +295,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.sum("attribute")
|
let term = SelectTerm<NSManagedObject>.sum("attribute")
|
||||||
XCTAssertEqual(term, SelectTerm.sum("attribute"))
|
XCTAssertEqual(term, SelectTerm.sum("attribute"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
||||||
@@ -318,7 +319,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.sum("attribute", as: "alias")
|
let term = SelectTerm<NSManagedObject>.sum("attribute", as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
||||||
@@ -347,7 +348,7 @@ final class SelectTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.objectID()
|
let term = SelectTerm<NSManagedObject>.objectID()
|
||||||
XCTAssertEqual(term, SelectTerm.objectID())
|
XCTAssertEqual(term, SelectTerm.objectID())
|
||||||
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias"))
|
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute"))
|
XCTAssertNotEqual(term, SelectTerm.attribute("attribute"))
|
||||||
@@ -368,7 +369,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let term = SelectTerm.objectID(as: "alias")
|
let term = SelectTerm<NSManagedObject>.objectID(as: "alias")
|
||||||
XCTAssertEqual(term, SelectTerm.objectID(as: "alias"))
|
XCTAssertEqual(term, SelectTerm.objectID(as: "alias"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2"))
|
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2"))
|
||||||
XCTAssertNotEqual(term, SelectTerm.objectID())
|
XCTAssertNotEqual(term, SelectTerm.objectID())
|
||||||
@@ -393,12 +394,12 @@ final class SelectTests: XCTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatSelectClauses_ConfigureCorrectly() {
|
dynamic func test_ThatSelectClauses_ConfigureCorrectly() {
|
||||||
|
|
||||||
let term1 = SelectTerm.attribute("attribute1")
|
let term1 = SelectTerm<NSManagedObject>.attribute("attribute1")
|
||||||
let term2 = SelectTerm.attribute("attribute2")
|
let term2 = SelectTerm<NSManagedObject>.attribute("attribute2")
|
||||||
let term3 = SelectTerm.attribute("attribute3")
|
let term3 = SelectTerm<NSManagedObject>.attribute("attribute3")
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let select = Select<Int>(term1, term2, term3)
|
let select = Select<NSManagedObject, Int>(term1, term2, term3)
|
||||||
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
||||||
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
||||||
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
||||||
@@ -408,7 +409,7 @@ final class SelectTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let select = Select<Int>([term1, term2, term3])
|
let select = Select<NSManagedObject, Int>([term1, term2, term3])
|
||||||
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
||||||
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
||||||
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// SetupTests.swift
|
// SetupTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,9 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
@@ -37,9 +40,10 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let schemaHistory = SchemaHistory(
|
let schemaHistory = SchemaHistory(
|
||||||
modelName: "Model",
|
XcodeDataModelSchema.from(
|
||||||
bundle: Bundle(for: type(of: self)),
|
modelName: "Model",
|
||||||
migrationChain: nil
|
bundle: Bundle.module
|
||||||
|
)
|
||||||
)
|
)
|
||||||
let stack = DataStack(schemaHistory: schemaHistory)
|
let stack = DataStack(schemaHistory: schemaHistory)
|
||||||
XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel)
|
XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel)
|
||||||
@@ -55,9 +59,6 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
XCTAssertTrue(stack.schemaHistory.migrationChain.isEmpty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.isEmpty)
|
||||||
XCTAssertTrue(stack.schemaHistory.migrationChain.rootVersions.isEmpty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.rootVersions.isEmpty)
|
||||||
XCTAssertTrue(stack.schemaHistory.migrationChain.leafVersions.isEmpty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.leafVersions.isEmpty)
|
||||||
|
|
||||||
CoreStore.defaultStack = stack
|
|
||||||
XCTAssertEqual(CoreStore.defaultStack, stack)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -66,16 +67,13 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
let stack = self.expectLogger([.logWarning]) {
|
let stack = self.expectLogger([.logWarning]) {
|
||||||
|
|
||||||
DataStack(
|
DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self)),
|
bundle: Bundle.module,
|
||||||
migrationChain: migrationChain
|
migrationChain: migrationChain
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(stack.modelVersion, "Model")
|
XCTAssertEqual(stack.modelVersion, "Model")
|
||||||
XCTAssertEqual(stack.schemaHistory.migrationChain, migrationChain)
|
XCTAssertEqual(stack.schemaHistory.migrationChain, migrationChain)
|
||||||
|
|
||||||
CoreStore.defaultStack = stack
|
|
||||||
XCTAssertEqual(CoreStore.defaultStack, stack)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,8 +81,8 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -138,8 +136,8 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -206,8 +204,8 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
try! stack.addStorageAndWait(sqliteStore)
|
try! stack.addStorageAndWait(sqliteStore)
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
@@ -225,10 +223,10 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
try sqliteStore.eraseStorageAndWait(
|
try sqliteStore.cs_eraseStorageAndWait(
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
)
|
)
|
||||||
@@ -243,7 +241,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
@@ -258,8 +256,8 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -326,10 +324,17 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
|
)
|
||||||
|
try! stack.addStorageAndWait(
|
||||||
|
SQLiteStore.legacy(
|
||||||
|
fileName: sqliteStore.fileURL.lastPathComponent,
|
||||||
|
configuration: sqliteStore.configuration,
|
||||||
|
migrationMappingProviders: sqliteStore.migrationMappingProviders,
|
||||||
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
|
)
|
||||||
)
|
)
|
||||||
try! stack.addStorageAndWait(sqliteStore)
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
}
|
}
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
@@ -345,10 +350,10 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle.module
|
||||||
)
|
)
|
||||||
try sqliteStore.eraseStorageAndWait(
|
try sqliteStore.cs_eraseStorageAndWait(
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
)
|
)
|
||||||
@@ -363,7 +368,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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?
|
||||||
}
|
}
|
||||||
@@ -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?
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// TransactionTests.swift
|
// TransactionTests.swift
|
||||||
// CoreStore
|
// CoreStore
|
||||||
//
|
//
|
||||||
// Copyright © 2016 John Rommel Estropia
|
// Copyright © 2018 John Rommel Estropia
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@testable
|
@testable
|
||||||
@@ -69,9 +70,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
@@ -84,14 +85,14 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let updateExpectation = self.expectation(description: "update")
|
let updateExpectation = self.expectation(description: "update")
|
||||||
let hasChanges: Bool = try! stack.perform(
|
let hasChanges: Bool = try stack.perform(
|
||||||
synchronous: { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
|
|
||||||
updateExpectation.fulfill()
|
updateExpectation.fulfill()
|
||||||
}
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
// TODO: convert fetch methods to throwing methods
|
// TODO: convert fetch methods to throwing methods
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -107,9 +108,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
@@ -128,7 +129,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
deleteExpectation.fulfill()
|
deleteExpectation.fulfill()
|
||||||
}
|
}
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = try transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
return transaction.hasChanges
|
return transaction.hasChanges
|
||||||
}
|
}
|
||||||
@@ -141,9 +142,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,10 +185,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
@@ -206,7 +207,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
updateExpectation.fulfill()
|
updateExpectation.fulfill()
|
||||||
}
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -226,10 +227,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
@@ -248,7 +249,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
deleteExpectation.fulfill()
|
deleteExpectation.fulfill()
|
||||||
}
|
}
|
||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
return transaction.hasChanges
|
return transaction.hasChanges
|
||||||
@@ -262,8 +263,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,17 +295,17 @@ final class TransactionTests: BaseTestCase {
|
|||||||
)
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
}
|
}
|
||||||
let testDate = Date()
|
let testDate = Date()
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
let dataPrepared: Void? = try? stack.perform(
|
try stack.perform(
|
||||||
synchronous: { (transaction) in
|
synchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
@@ -313,10 +314,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if dataPrepared != nil {
|
createExpectation.fulfill()
|
||||||
|
|
||||||
createExpectation.fulfill()
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
@@ -329,7 +327,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
updateDiscardExpectation.fulfill()
|
updateDiscardExpectation.fulfill()
|
||||||
}
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -343,9 +341,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
)
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
@@ -362,7 +360,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
deleteDiscardExpectation.fulfill()
|
deleteDiscardExpectation.fulfill()
|
||||||
}
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -374,9 +372,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
)
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
@@ -386,8 +384,6 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@available(OSX 10.12, *)
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
|
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
|
||||||
|
|
||||||
@@ -396,15 +392,15 @@ final class TransactionTests: BaseTestCase {
|
|||||||
let observer = TestListObserver()
|
let observer = TestListObserver()
|
||||||
let monitor = stack.monitorList(
|
let monitor = stack.monitorList(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
OrderBy(.ascending("testEntityID"))
|
OrderBy<TestEntity1>(.ascending("testEntityID"))
|
||||||
)
|
)
|
||||||
monitor.addObserver(observer)
|
monitor.addObserver(observer)
|
||||||
|
|
||||||
XCTAssertFalse(monitor.hasObjects())
|
XCTAssertFalse(monitor.hasObjects())
|
||||||
|
|
||||||
var events = 0
|
var events = 0
|
||||||
let willChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorWillChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -417,8 +413,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
return events == 0
|
return events == 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didInsertObjectExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitor:didInsertObject:toIndexPath:",
|
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -431,9 +427,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
["indexPath", "object"]
|
["indexPath", "object"]
|
||||||
)
|
)
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
let indexPath = userInfo?["indexPath"] as? IndexPath
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
XCTAssertEqual(indexPath?.section, 0)
|
||||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
XCTAssertEqual(indexPath?.item, 0)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -447,8 +443,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
return events == 1
|
return events == 1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
let didChangeExpectation = self.expectation(
|
_ = self.expectation(
|
||||||
forNotification: "listMonitorDidChange:",
|
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||||
object: observer,
|
object: observer,
|
||||||
handler: { (note) -> Bool in
|
handler: { (note) -> Bool in
|
||||||
|
|
||||||
@@ -520,19 +516,26 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
do {
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
XCTAssertNotNil(object)
|
|
||||||
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
XCTAssertNotNil(object)
|
||||||
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
createExpectation.fulfill()
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
|
createExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -546,7 +549,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -560,16 +563,23 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
do {
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
XCTAssertNotNil(object)
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
updateExpectation.fulfill()
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
|
updateExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -583,7 +593,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = try transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
return transaction.hasChanges
|
return transaction.hasChanges
|
||||||
@@ -591,12 +601,19 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
do {
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(object)
|
|
||||||
deleteExpectation.fulfill()
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
|
XCTAssertNil(object)
|
||||||
|
deleteExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -604,8 +621,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -631,17 +648,24 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
do {
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
|
||||||
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
XCTAssertNotNil(object)
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
createExpectation.fulfill()
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
|
createExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -655,7 +679,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -669,17 +693,24 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
do {
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
|
||||||
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
XCTAssertNotNil(object)
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
updateExpectation.fulfill()
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
|
updateExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -693,7 +724,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
return transaction.hasChanges
|
return transaction.hasChanges
|
||||||
@@ -701,11 +732,21 @@ final class TransactionTests: BaseTestCase {
|
|||||||
success: { (hasChanges) in
|
success: { (hasChanges) in
|
||||||
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
do {
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
|
||||||
|
let configCount = try stack.fetchCount(From<TestEntity1>("Config1"))
|
||||||
deleteExpectation.fulfill()
|
XCTAssertEqual(configCount, 0)
|
||||||
|
|
||||||
|
let defaultCount = try stack.fetchCount(From<TestEntity1>(nil))
|
||||||
|
XCTAssertEqual(defaultCount, 0)
|
||||||
|
|
||||||
|
deleteExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
failure: { _ in
|
failure: { _ in
|
||||||
|
|
||||||
@@ -713,8 +754,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -737,7 +778,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
createDiscardExpectation.fulfill()
|
createDiscardExpectation.fulfill()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
},
|
},
|
||||||
success: {
|
success: { _ in
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
},
|
},
|
||||||
@@ -754,8 +795,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Bool in
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
@@ -782,7 +823,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Void in
|
asynchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -795,7 +836,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
},
|
},
|
||||||
success: {
|
success: { _ in
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
},
|
},
|
||||||
@@ -811,9 +852,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
stack.perform(
|
stack.perform(
|
||||||
asynchronous: { (transaction) -> Void in
|
asynchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
@@ -828,27 +869,34 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
try transaction.cancel()
|
try transaction.cancel()
|
||||||
},
|
},
|
||||||
success: {
|
success: { _ in
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
},
|
},
|
||||||
failure: { (error) in
|
failure: { (error) in
|
||||||
|
|
||||||
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
do {
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
XCTAssertNotNil(object)
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
deleteDiscardExpectation.fulfill()
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
|
deleteDiscardExpectation.fulfill()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -878,9 +926,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
@@ -897,7 +945,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -911,9 +959,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = try stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
@@ -927,7 +975,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = try transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -935,8 +983,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
@@ -967,10 +1015,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
@@ -984,7 +1032,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -998,10 +1046,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>("Config1"))
|
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
@@ -1015,7 +1063,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -1023,8 +1071,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertTrue(transaction.hasChanges)
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
try transaction.commitAndWait()
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
@@ -1050,11 +1098,11 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let testDate = Date()
|
let testDate = Date()
|
||||||
@@ -1079,7 +1127,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -1090,8 +1138,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
if let object = transaction.fetchOne(From<TestEntity1>()) {
|
if let object = try transaction.fetchOne(From<TestEntity1>()) {
|
||||||
|
|
||||||
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object.testString, "string1")
|
XCTAssertEqual(object.testString, "string1")
|
||||||
@@ -1103,8 +1151,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
if let object = stack.fetchOne(From<TestEntity1>()) {
|
if let object = try stack.fetchOne(From<TestEntity1>()) {
|
||||||
|
|
||||||
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object.testString, "string1")
|
XCTAssertEqual(object.testString, "string1")
|
||||||
@@ -1119,7 +1167,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
return
|
||||||
@@ -1128,8 +1176,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
transaction.rollback()
|
transaction.rollback()
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
if let object = transaction.fetchOne(From<TestEntity1>()) {
|
if let object = try transaction.fetchOne(From<TestEntity1>()) {
|
||||||
|
|
||||||
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object.testString, "string1")
|
XCTAssertEqual(object.testString, "string1")
|
||||||
@@ -1141,8 +1189,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
if let object = stack.fetchOne(From<TestEntity1>()) {
|
if let object = try stack.fetchOne(From<TestEntity1>()) {
|
||||||
|
|
||||||
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object.testString, "string1")
|
XCTAssertEqual(object.testString, "string1")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
55
CoreStoreTests/VersionLockTests.swift
Normal file
55
CoreStoreTests/VersionLockTests.swift
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// VersionLockTests.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2018 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable
|
||||||
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
|
//MARK: - VersionLockTests
|
||||||
|
|
||||||
|
final class VersionLockTests: XCTestCase {
|
||||||
|
|
||||||
|
@objc
|
||||||
|
dynamic func test_ThatVersionLocksProduceCorrectHashes() {
|
||||||
|
|
||||||
|
let versionLock: VersionLock = [
|
||||||
|
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||||
|
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||||
|
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
|
||||||
|
]
|
||||||
|
XCTAssertEqual(
|
||||||
|
versionLock.description,
|
||||||
|
"""
|
||||||
|
[
|
||||||
|
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||||
|
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||||
|
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user