#import "MoneyTest.h"

#import "Money.h"
#import "MoneyBag.h"

@implementation MoneyTest

- (void)setUp {
    f12CHF = [[Money alloc] initWithAmount:12 currency:@"CHF"];
    f14CHF = [[Money alloc] initWithAmount:14 currency:@"CHF"];
    f7USD = [[Money alloc] initWithAmount:7 currency:@"USD"];
    f21USD = [[Money alloc] initWithAmount:21 currency:@"USD"];
    
    fMB1 = [[MoneyBag alloc] initWithMoney:f12CHF money:f7USD];
    fMB2 = [[MoneyBag alloc] initWithMoney:f14CHF money:f21USD];
}

- (void)tearDown {
    [f12CHF release];
    [f14CHF release];
    [f7USD release];
    [f21USD release];

    [fMB1 release];
    [fMB2 release];
}

- (void)testBagMultiply {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:24 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:14 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[fMB1 multiply:2] equals:expected];
    [self assert:[fMB1 multiply:1] equals:fMB1];
    [self assertTrue:[[fMB1 multiply:0] isZero]];
}

- (void)testBagNegate {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:-12 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:-7 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[fMB1 negate] equals:expected];
}

- (void)testBagSimpleAdd {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:26 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:7 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[fMB1 add:f14CHF] equals:expected];
}

- (void)testBagSubtract {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:-2 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:-14 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[fMB1 subtract:fMB2] equals:expected];
}

- (void)testBagSumAdd {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:26 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:28 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[fMB1 add:fMB2] equals:expected];
}

- (void)testIsZero {
    NSArray *array;
    MoneyBag *bag;
    
    [self assertTrue:[[fMB1 subtract:fMB1] isZero]];
    
    array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:0 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:0 currency:@"USD"] autorelease], nil];
    bag = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assertTrue:[bag isZero]];
}

- (void)testMixedSimpleAdd {
    NSArray *array = [NSArray arrayWithObjects:f12CHF, f7USD, nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[f12CHF add:f7USD] equals:expected];
}

- (void)testMoneyBagIsEqual {
    MoneyBag *equal;
    
    [self assertFalse:[fMB1 isEqual:nil]];
    
    [self assert:fMB1 equals:fMB1];
    equal = [[[MoneyBag alloc] initWithMoney:[[[Money alloc] initWithAmount:12 currency:@"CHF"] autorelease] money:[[[Money alloc] initWithAmount:7 currency:@"USD"] autorelease]] autorelease];
    [self assertTrue:[fMB1 isEqual:equal]];
    [self assertFalse:[fMB1 isEqual:f12CHF]];
    [self assertFalse:[f12CHF isEqual:fMB1]];
    [self assertFalse:[fMB1 isEqual:fMB2]];
}

- (void)testMoneyIsEqual {
    Money *equalMoney;
    
    [self assertFalse:[f12CHF isEqual:nil]];
    equalMoney = [[[Money alloc] initWithAmount:12 currency:@"CHF"] autorelease];
    [self assert:f12CHF equals:f12CHF];
    [self assert:f12CHF equals:equalMoney];
    [self assertFalse:[f12CHF isEqual:f14CHF]];
}

- (void)testNormalize {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:26 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:28 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:6 currency:@"CHF"] autorelease], nil];
    MoneyBag *moneyBag = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    NSArray *expected = [NSArray arrayWithObject:[[[Money alloc] initWithAmount:60 currency:@"CHF"] autorelease]];
    MoneyBag *expectedBag = [[[MoneyBag alloc] initWithMoneyArray:expected] autorelease];
    [self assert:moneyBag equals:expectedBag];
}

- (void)testNormalize2 {
    Money *expected = [[[Money alloc] initWithAmount:7 currency:@"USD"] autorelease];
    [self assert:[fMB1 subtract:f12CHF] equals:expected];
}

- (void)testNormalize3 {
    NSArray *s1 = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:12 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:3 currency:@"USD"] autorelease], nil];
    MoneyBag *ms1 = [[[MoneyBag alloc] initWithMoneyArray:s1] autorelease];
    Money *expected = [[[Money alloc] initWithAmount:4 currency:@"USD"] autorelease];
    [self assert:[fMB1 subtract:ms1] equals:expected];
}

- (void)testNormalize4 {
    NSArray *s1 = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:12 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:3 currency:@"USD"] autorelease], nil];
    MoneyBag *ms1 = [[[MoneyBag alloc] initWithMoneyArray:s1] autorelease];
    Money *expected = [[[Money alloc] initWithAmount:-3 currency:@"USD"] autorelease];
    [self assert:[f12CHF subtract:ms1] equals:expected];
}

- (void)testPrint {
    [self assertString:[f12CHF description] equals:@"[12 CHF]"];
}

- (void)testSimpleAdd {
    Money *expected = [[[Money alloc] initWithAmount:26 currency:@"CHF"] autorelease];
    [self assert:[f12CHF add:f14CHF] equals:expected];
}

- (void)testSimpleBagAdd {
    NSArray *array = [NSArray arrayWithObjects:[[[Money alloc] initWithAmount:26 currency:@"CHF"] autorelease], [[[Money alloc] initWithAmount:7 currency:@"USD"] autorelease], nil];
    MoneyBag *expected = [[[MoneyBag alloc] initWithMoneyArray:array] autorelease];
    [self assert:[f14CHF add:fMB1] equals:expected];
}

- (void)testSimpleMultiply {
    Money *expected = [[[Money alloc] initWithAmount:28 currency:@"CHF"] autorelease];
    [self assert:[f14CHF multiply:2] equals:expected];
}

- (void)testSimpleNegate {
    Money *expected = [[[Money alloc] initWithAmount:-14 currency:@"CHF"] autorelease];
    [self assert:[f14CHF negate] equals:expected];
}

- (void)testSimpleSubtract {
    Money *expected = [[[Money alloc] initWithAmount:2 currency:@"CHF"] autorelease];
    [self assert:[f14CHF subtract:f12CHF] equals:expected];
}

@end
