Commit d8464f93 by Brent Gulanowski

Add new model and equality support. New test. Refactor tests.

parent 0fb34f84
...@@ -38,6 +38,10 @@ static NSString * const LeafEntity = @"Leaf"; ...@@ -38,6 +38,10 @@ static NSString * const LeafEntity = @"Leaf";
static NSString * const NestEntity = @"Nest"; static NSString * const NestEntity = @"Nest";
static NSString * const BirdEntity = @"Bird"; static NSString * const BirdEntity = @"Bird";
@interface NSIndexSet (BUYTestAdditions)
+ (instancetype)indexSetWithIndexes:(NSArray *)indexes;
@end
@interface BUYPropertyDescriptionAdditionsTests : XCTestCase @interface BUYPropertyDescriptionAdditionsTests : XCTestCase
@property (nonatomic) NSManagedObjectModel *model; @property (nonatomic) NSManagedObjectModel *model;
@property (nonatomic) TestModelManager *modelManager; @property (nonatomic) TestModelManager *modelManager;
...@@ -183,29 +187,68 @@ static NSString * const BirdEntity = @"Bird"; ...@@ -183,29 +187,68 @@ static NSString * const BirdEntity = @"Bird";
{ {
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil]; Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *leafRelationship = [self relationshipWithName:@"leaves" forEntity:BranchEntity]; NSRelationshipDescription *leafRelationship = [self relationshipWithName:@"leaves" forEntity:BranchEntity];
id json = @[
@{ // Semi-random leaf objects
@"date" : @"2001-01-21T00:00:00 +0000", branch.leaves = [NSSet setWithArray:@[[self leafWithDate:[self dateWithComponents:[self november4_1605]] tags:[self tagsWithIndexes:@[@1, @5, @11]]],
@"tags" : @"test one two" [self leafWithDate:[self dateWithComponents:[self november4_1605]] tags:[self tagsWithIndexes:@[@9]]],
}, [self leafWithDate:[self dateWithComponents:[self november4_1605]] tags:[self tagsWithIndexes:@[@12, @0, @8, @4]]]]];
@{ id json = [leafRelationship buy_JSONForValue:branch.leaves];
@"date" : @"2010-06-11T00:00:00 +0000", id actual = [leafRelationship buy_valueForJSON:json object:branch];
@"tags" : @"phone" XCTAssertEqualObjects(actual, branch.leaves);
}, }
@{
@"date" : @"2013-11-03T00:00:00 +0000", - (Leaf *)leafWithDate:(NSDate *)date tags:(NSSet *)tags
@"tags" : @"song tune album" {
}, Leaf *leaf = [self.modelManager buy_objectWithEntityName:[Leaf entityName] JSONDictionary:nil];
]; leaf.date = date;
NSSet *object = [leafRelationship buy_valueForJSON:json object:branch]; leaf.tags = tags;
XCTAssertTrue([object isKindOfClass:[NSSet class]]); return leaf;
XCTAssertTrue([[object anyObject] isKindOfClass:[Leaf class]]); }
NSSet *expected = [NSSet setWithObjects:
[NSSet setWithObjects:@"test", @"one", @"two", nil], - (NSSet *)tagsWithIndexes:(NSArray *)indexes
[NSSet setWithObjects:@"phone", nil], {
[NSSet setWithObjects:@"song", @"tune", @"album", nil], static NSArray *tags;
nil]; static dispatch_once_t onceToken;
XCTAssertEqualObjects(expected, [object valueForKey:@"tags"]); dispatch_once(&onceToken, ^{
tags = @[@"one", @"two", @"three", @"hot", @"urgent", @"important", @"red", @"green", @"blue", @"animal", @"vegetable", @"mineral", @"fungus"];
});
return [NSSet setWithArray:[tags objectsAtIndexes:[NSIndexSet indexSetWithIndexes:indexes]]];
}
- (NSDate *)dateWithComponents:(NSDateComponents *)components
{
return [[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian] dateFromComponents:components];
}
- (NSDateComponents *)november4_1605
{
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = 1605;
components.month = 11;
components.day = 4;
return components;
}
- (NSDateComponents *)june21_1970
{
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = 1970;
components.month = 6;
components.day = 21;
return components;
}
@end
@implementation NSIndexSet (BUYTestAdditions)
+ (instancetype)indexSetWithIndexes:(NSArray *)indexes
{
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
for (NSNumber *index in indexes) {
[indexSet addIndex:index.unsignedIntegerValue];
}
return indexSet;
} }
@end @end
...@@ -3,7 +3,12 @@ ...@@ -3,7 +3,12 @@
<entity name="Bird" representedClassName="Bird" syncable="YES"> <entity name="Bird" representedClassName="Bird" syncable="YES">
<attribute name="colour" optional="YES" attributeType="String" syncable="YES"/> <attribute name="colour" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" syncable="YES"/> <attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" syncable="YES"/>
<relationship name="nests" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Nest" inverseName="bird" inverseEntity="Nest" syncable="YES"/> <relationship name="nests" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Nest" inverseName="bird" inverseEntity="Nest" syncable="YES">
<userInfo>
<entry key="JSONPropertyKey" value="nest_ids"/>
<entry key="key" value="value"/>
</userInfo>
</relationship>
</entity> </entity>
<entity name="Branch" representedClassName="Branch" syncable="YES"> <entity name="Branch" representedClassName="Branch" syncable="YES">
<attribute name="ornaments" optional="YES" attributeType="Transformable" syncable="YES"> <attribute name="ornaments" optional="YES" attributeType="Transformable" syncable="YES">
...@@ -16,6 +21,12 @@ ...@@ -16,6 +21,12 @@
<relationship name="nest" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Nest" inverseName="branch" inverseEntity="Nest" syncable="YES"/> <relationship name="nest" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="Nest" inverseName="branch" inverseEntity="Nest" syncable="YES"/>
<relationship name="root" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Root" inverseName="branches" inverseEntity="Root" syncable="YES"/> <relationship name="root" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Root" inverseName="branches" inverseEntity="Root" syncable="YES"/>
</entity> </entity>
<entity name="Forest" syncable="YES">
<relationship name="trees" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Root" inverseName="forest" inverseEntity="Root" syncable="YES"/>
<userInfo>
<entry key="private" value="YES"/>
</userInfo>
</entity>
<entity name="Leaf" representedClassName="Leaf" syncable="YES"> <entity name="Leaf" representedClassName="Leaf" syncable="YES">
<attribute name="date" optional="YES" attributeType="Date" syncable="YES"> <attribute name="date" optional="YES" attributeType="Date" syncable="YES">
<userInfo> <userInfo>
...@@ -50,12 +61,14 @@ ...@@ -50,12 +61,14 @@
</userInfo> </userInfo>
</attribute> </attribute>
<relationship name="branches" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Branch" inverseName="root" inverseEntity="Branch" syncable="YES"/> <relationship name="branches" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="Branch" inverseName="root" inverseEntity="Branch" syncable="YES"/>
<relationship name="forest" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Forest" inverseName="trees" inverseEntity="Forest" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="Root" positionX="-63" positionY="-18" width="128" height="120"/> <element name="Bird" positionX="151" positionY="111" width="128" height="90"/>
<element name="Branch" positionX="-63" positionY="0" width="128" height="105"/> <element name="Branch" positionX="-288" positionY="-3" width="128" height="105"/>
<element name="Leaf" positionX="-45" positionY="18" width="128" height="90"/> <element name="Leaf" positionX="-72" positionY="-18" width="128" height="90"/>
<element name="Bird" positionX="-36" positionY="45" width="128" height="90"/> <element name="Nest" positionX="-72" positionY="126" width="128" height="90"/>
<element name="Nest" positionX="-27" positionY="54" width="128" height="90"/> <element name="Root" positionX="-504" positionY="-18" width="128" height="133"/>
<element name="Forest" positionX="-477" positionY="137" width="128" height="58"/>
</elements> </elements>
</model> </model>
\ No newline at end of file
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
@property (nonatomic, strong) TestModelManager *modelManager; @property (nonatomic, strong) TestModelManager *modelManager;
@end @end
@class Leaf, Nest; @class Leaf, Nest, Root;
@interface Bird : TestModel @interface Bird : TestModel
@property (nonatomic) NSNumber *identifier; @property (nonatomic) NSNumber *identifier;
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
@property (nonatomic) Nest *nest; @property (nonatomic) Nest *nest;
@end @end
@interface Forest : TestModel
@property (nonatomic) NSSet<Root *> *trees;
@end
@interface Leaf : TestModel @interface Leaf : TestModel
@property (nonatomic) NSDate *date; @property (nonatomic) NSDate *date;
@property (nonatomic) NSSet<NSString *> *tags; @property (nonatomic) NSSet<NSString *> *tags;
...@@ -42,6 +46,7 @@ ...@@ -42,6 +46,7 @@
@interface Nest : TestModel @interface Nest : TestModel
@property (nonatomic) NSNumber *eggCount; @property (nonatomic) NSNumber *eggCount;
@property (nonatomic) Bird *bird; @property (nonatomic) Bird *bird;
@property (nonatomic) Branch *branch;
@end @end
@interface Root : TestModel @interface Root : TestModel
...@@ -49,4 +54,6 @@ ...@@ -49,4 +54,6 @@
@property (nonatomic) NSDecimalNumber *age; @property (nonatomic) NSDecimalNumber *age;
@property (nonatomic) NSString *name; @property (nonatomic) NSString *name;
@property (nonatomic) NSURL *url; @property (nonatomic) NSURL *url;
@property (nonatomic) NSSet<Branch *> *branches;
@property (nonatomic) Forest *forest;
@end @end
...@@ -122,6 +122,11 @@ ...@@ -122,6 +122,11 @@
return NO; return NO;
} }
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] || [object isMemberOfClass:[self class]];
}
@end @end
#pragma mark - Models #pragma mark - Models
...@@ -135,16 +140,113 @@ ...@@ -135,16 +140,113 @@
return bird; return bird;
} }
- (BOOL)isEqual:(Bird *)otherModel
{
return ([super isEqual:otherModel] &&
[self.identifier isEqual:otherModel.identifier] &&
[self.colour isEqualToString:otherModel.colour]);
}
- (NSUInteger)hash
{
NSUInteger hash = self.identifier.hash;
hash = (hash << 5) ^ self.colour.hash;
return hash;
}
@end @end
@implementation Branch @implementation Branch
- (BOOL)isEqual:(Branch *)otherModel
{
return ([super isEqual:otherModel] &&
[self.ornaments isEqual:otherModel.ornaments] &&
[self.leaves isEqual:otherModel.leaves]);
}
- (NSUInteger)hash
{
NSUInteger hash = self.ornaments.hash;
hash = (hash << 5) ^ self.leaves.hash;
return hash;
}
@end
@implementation Forest
- (BOOL)isEqual:(Forest *)object
{
return ([super isEqual:object] &&
[self.trees isEqual:object.trees]);
}
- (NSUInteger)hash
{
return self.trees.hash;
}
@end @end
@implementation Leaf @implementation Leaf
- (BOOL)isEqual:(Leaf *)object
{
return ([super isEqual:object] &&
[self.date isEqual:object.date] &&
[self.tags isEqual:object.tags]);
}
- (NSUInteger)hash
{
NSUInteger hash = self.date.hash;
hash = (hash << 5) ^ self.tags.hash;
return hash;
}
@end @end
@implementation Nest @implementation Nest
- (BOOL)isEqual:(Nest *)object
{
return ([super isEqual:object] &&
[self.eggCount isEqual:object.eggCount] &&
((self.bird == nil && object.bird == nil) || [self.bird isEqual:object.bird]));
}
- (NSUInteger)hash
{
NSUInteger hash = self.eggCount.hash;
if (self.bird) {
hash = (hash << 5) ^ self.bird.hash;
}
return hash;
}
@end @end
@implementation Root @implementation Root
- (BOOL)isEqual:(Root *)object
{
return ([super isEqual:object] &&
[self.identifier isEqual:object.identifier] &&
[self.age isEqual:object.age] &&
[self.name isEqual:object.name] &&
[self.url isEqual:object.url] &&
[self.branches isEqual:object.branches]);
}
- (NSUInteger)hash
{
NSUInteger hash = self.identifier.hash;
hash = (hash << 5) ^ self.age.hash;
hash = (hash << 5) ^ self.name.hash;
hash = (hash << 5) ^ self.url.hash;
hash = (hash << 5) ^ self.branches.hash;
return hash;
}
@end @end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment