//
//  SubstituteCollectionTests.m
//  MealBuilder
//
//  Created by Phil Horowitz on 2/25/13.
//  Copyright (c) 2013 Phil Horowitz. All rights reserved.
//

#import "SubstituteCollectionTests.h"
#import "SubstitutableCollection.h"

@interface TestNamed : NSObject <Named>
@property (strong, nonatomic) NSString *name;
@end

@implementation TestNamed
-(NSString *)name{
    if (!_name){
        _name = @"";
    }
    return _name;
}
@end



@implementation SubstituteCollectionTests

#pragma mark addItem tests
-(void)testAddItem{
    TestNamed *item = [[TestNamed alloc] init];
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    
    STAssertEqualObjects(item, [collection getItems][0], @"Should be able to add and fetch item");
}

-(void)testAddDupilcateItem{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Test";
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:item];
    
    STAssertEquals([[collection getItems] count], 1U, @"Adding a duplicate object should fail");
}

#pragma mark addItem:AsSubstituteFor: tests
-(void)testAddSubstitute{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Test";
    TestNamed *sub = [[TestNamed alloc] init];
    sub.name = @"Sub";
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:sub asSubstitutionFor:item];
    
    STAssertEqualObjects([collection getSubstitutionsForItem:item][0], sub, @"Should be able to add and fetch substitutitons for an item");
}
-(void)testAddDuplicateSubstitute{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Test";
    TestNamed *sub = [[TestNamed alloc] init];
    sub.name = @"Sub";
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:sub asSubstitutionFor:item];
    [collection addItem:sub asSubstitutionFor:item];
    
    STAssertEquals(1U, [[collection getSubstitutionsForItem:item] count], @"Substitutions should be unique");
    
}
-(void)testAddingSameNameAsSubstitute{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Test";
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:item asSubstitutionFor:item];
    
    STAssertEquals([[collection getSubstitutionsForItem:item] count], 0U, @"Adding an object as a substitute that has the same name as its item should not work");
    
}
-(void)testAddingExistingOtherItemAsSubstitute{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Item1";
    TestNamed *item2 = [[TestNamed alloc] init];
    item2.name = @"Item2";
    
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:item2];
    [collection addItem:item asSubstitutionFor:item2];
    STAssertEquals(0U, [[collection getSubstitutionsForItem:item2] count], @"Adding a substitute item that's already an item elsewhere should be invalid");
}

#pragma mark substituteItem:with: tests
-(void)testSubstituteItem{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Item";
    TestNamed *sub = [[TestNamed alloc] init];
    item.name = @"Sub";
    
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection addItem:sub asSubstitutionFor:item];
    [collection substituteItem:item with:sub];
    
    STAssertEqualObjects([collection getItems][0], sub, @"Performing a substitutiton should substitute the item");
    
    NSArray *newSubs = [collection getSubstitutionsForItem:sub];
    STAssertEqualObjects(newSubs[0], item, @"After a substitution, the old item should be a substitution for the new one");
}

-(void)testSubstituteItemWithInvalidSub{
    TestNamed *item = [[TestNamed alloc] init];
    item.name = @"Item";
    TestNamed *sub = [[TestNamed alloc] init];
    item.name = @"Sub";
    
    SubstitutableCollection *collection = [[SubstitutableCollection alloc] init];
    [collection addItem:item];
    [collection substituteItem:item with:sub];
    
    STAssertEqualObjects([collection getItems][0], item, @"Performing a substitution with an object that hasn't been added as a substiution should not substitute the item");
}

@end
