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";
static NSString * const NestEntity = @"Nest";
static NSString * const BirdEntity = @"Bird";
@interface NSIndexSet (BUYTestAdditions)
+ (instancetype)indexSetWithIndexes:(NSArray *)indexes;
@end
@interface BUYPropertyDescriptionAdditionsTests : XCTestCase
@property (nonatomic) NSManagedObjectModel *model;
@property (nonatomic) TestModelManager *modelManager;
......@@ -183,29 +187,68 @@ static NSString * const BirdEntity = @"Bird";
{
Branch *branch = [self.modelManager buy_objectWithEntityName:BranchEntity JSONDictionary:nil];
NSRelationshipDescription *leafRelationship = [self relationshipWithName:@"leaves" forEntity:BranchEntity];
id json = @[
@{
@"date" : @"2001-01-21T00:00:00 +0000",
@"tags" : @"test one two"
},
@{
@"date" : @"2010-06-11T00:00:00 +0000",
@"tags" : @"phone"
},
@{
@"date" : @"2013-11-03T00:00:00 +0000",
@"tags" : @"song tune album"
},
];
NSSet *object = [leafRelationship buy_valueForJSON:json object:branch];
XCTAssertTrue([object isKindOfClass:[NSSet class]]);
XCTAssertTrue([[object anyObject] isKindOfClass:[Leaf class]]);
NSSet *expected = [NSSet setWithObjects:
[NSSet setWithObjects:@"test", @"one", @"two", nil],
[NSSet setWithObjects:@"phone", nil],
[NSSet setWithObjects:@"song", @"tune", @"album", nil],
nil];
XCTAssertEqualObjects(expected, [object valueForKey:@"tags"]);
// Semi-random leaf objects
branch.leaves = [NSSet setWithArray:@[[self leafWithDate:[self dateWithComponents:[self november4_1605]] tags:[self tagsWithIndexes:@[@1, @5, @11]]],
[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];
id actual = [leafRelationship buy_valueForJSON:json object:branch];
XCTAssertEqualObjects(actual, branch.leaves);
}
- (Leaf *)leafWithDate:(NSDate *)date tags:(NSSet *)tags
{
Leaf *leaf = [self.modelManager buy_objectWithEntityName:[Leaf entityName] JSONDictionary:nil];
leaf.date = date;
leaf.tags = tags;
return leaf;
}
- (NSSet *)tagsWithIndexes:(NSArray *)indexes
{
static NSArray *tags;
static dispatch_once_t onceToken;
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
......@@ -3,7 +3,12 @@
<entity name="Bird" representedClassName="Bird" syncable="YES">
<attribute name="colour" optional="YES" attributeType="String" 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 name="Branch" representedClassName="Branch" syncable="YES">
<attribute name="ornaments" optional="YES" attributeType="Transformable" syncable="YES">
......@@ -16,6 +21,12 @@
<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"/>
</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">
<attribute name="date" optional="YES" attributeType="Date" syncable="YES">
<userInfo>
......@@ -50,12 +61,14 @@
</userInfo>
</attribute>
<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>
<elements>
<element name="Root" positionX="-63" positionY="-18" width="128" height="120"/>
<element name="Branch" positionX="-63" positionY="0" width="128" height="105"/>
<element name="Leaf" positionX="-45" positionY="18" width="128" height="90"/>
<element name="Bird" positionX="-36" positionY="45" width="128" height="90"/>
<element name="Nest" positionX="-27" positionY="54" width="128" height="90"/>
<element name="Bird" positionX="151" positionY="111" width="128" height="90"/>
<element name="Branch" positionX="-288" positionY="-3" width="128" height="105"/>
<element name="Leaf" positionX="-72" positionY="-18" width="128" height="90"/>
<element name="Nest" positionX="-72" positionY="126" 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>
</model>
\ No newline at end of file
......@@ -20,7 +20,7 @@
@property (nonatomic, strong) TestModelManager *modelManager;
@end
@class Leaf, Nest;
@class Leaf, Nest, Root;
@interface Bird : TestModel
@property (nonatomic) NSNumber *identifier;
......@@ -34,6 +34,10 @@
@property (nonatomic) Nest *nest;
@end
@interface Forest : TestModel
@property (nonatomic) NSSet<Root *> *trees;
@end
@interface Leaf : TestModel
@property (nonatomic) NSDate *date;
@property (nonatomic) NSSet<NSString *> *tags;
......@@ -42,6 +46,7 @@
@interface Nest : TestModel
@property (nonatomic) NSNumber *eggCount;
@property (nonatomic) Bird *bird;
@property (nonatomic) Branch *branch;
@end
@interface Root : TestModel
......@@ -49,4 +54,6 @@
@property (nonatomic) NSDecimalNumber *age;
@property (nonatomic) NSString *name;
@property (nonatomic) NSURL *url;
@property (nonatomic) NSSet<Branch *> *branches;
@property (nonatomic) Forest *forest;
@end
......@@ -122,6 +122,11 @@
return NO;
}
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] || [object isMemberOfClass:[self class]];
}
@end
#pragma mark - Models
......@@ -135,16 +140,113 @@
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
@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
@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
@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
@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
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