/
_StockMarketYearTest.java
107 lines (89 loc) · 4.65 KB
/
_StockMarketYearTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.jamesshore.finances.domain;
import static org.junit.Assert.*;
import org.junit.*;
public class _StockMarketYearTest {
private static final Year YEAR = new Year(2010);
private static final GrowthRate INTEREST_RATE = new GrowthRate(10);
private static final Dollars STARTING_BALANCE = new ValidDollars(10000);
private static final Dollars STARTING_PRINCIPAL = new ValidDollars(3000);
private static final TaxRate CAPITAL_GAINS_TAX_RATE = new TaxRate(25);
@Test
public void startingValues() {
StockMarketYear year = newYear();
assertEquals("year", YEAR, year.year());
assertEquals("starting balance", STARTING_BALANCE, year.startingBalance());
assertEquals("starting principal", STARTING_PRINCIPAL, year.startingCostBasis());
assertEquals("interest rate", INTEREST_RATE, year.growthRate());
assertEquals("capital gains tax rate", CAPITAL_GAINS_TAX_RATE, year.capitalGainsTaxRate());
assertEquals("total withdrawn default", new ValidDollars(0), year.totalSold());
}
@Test
public void totalSold() {
StockMarketYear year = newYear();
assertEquals("no sales", new ValidDollars(0), year.totalSellOrders());
year.sell(new ValidDollars(3000));
assertEquals("one sale", new ValidDollars(3000), year.totalSellOrders());
year.sell(new ValidDollars(750));
year.sell(new ValidDollars(1350));
assertEquals("multiple sales", new ValidDollars(5100), year.totalSellOrders());
}
@Test
public void capitalGainsTax() {
StockMarketYear year = newYear();
year.sell(new ValidDollars(4000));
assertEquals("capital gains tax includes tax on withdrawals to cover capital gains", new ValidDollars(1333), year.capitalGainsTaxIncurred());
assertEquals("total withdrawn includes capital gains tax", new ValidDollars(5333), year.totalSold());
}
@Test
public void treatAllWithdrawalsAsSubjectToCapitalGainsTaxUntilAllCapitalGainsHaveBeenSold() {
StockMarketYear year = newYear();
Dollars capitalGains = STARTING_BALANCE.minus(STARTING_PRINCIPAL);
year.sell(new ValidDollars(500));
assertEquals("pay tax on all entire withdrawal", new ValidDollars(167), year.capitalGainsTaxIncurred());
year.sell(capitalGains);
assertEquals("to match spreadsheet, we pay compounding tax on capital gains even when compounded amount is not capital gains", new ValidDollars(2333), year.capitalGainsTaxIncurred());
year.sell(new ValidDollars(1000));
assertEquals("pay no more tax once all capital gains withdrawn", new ValidDollars(2333), year.capitalGainsTaxIncurred());
}
@Test
public void interestEarned() {
StockMarketYear year = newYear();
assertEquals("basic interest earned", new ValidDollars(1000), year.growth());
year.sell(new ValidDollars(2000));
assertEquals("withdrawals (which pay capital gains tax) don't earn interest", new ValidDollars(733), year.growth());
}
@Test
public void endingPrincipal() {
StockMarketYear year = newYear();
year.sell(new ValidDollars(500));
assertEquals("withdrawals less than capital gains do not reduce principal", STARTING_PRINCIPAL, year.endingCostBasis());
year.sell(new ValidDollars(6500));
Dollars totalWithdrawn = new ValidDollars(9333);
Dollars capitalGains = new ValidDollars(7000);
Dollars principalReducedBy = totalWithdrawn.minus(capitalGains);
Dollars expectedPrincipal = STARTING_PRINCIPAL.minus(principalReducedBy);
assertEquals("principal should be reduced by difference between total withdrawals and capital gains", expectedPrincipal, year.endingCostBasis());
year.sell(new ValidDollars(1000));
assertEquals("principal goes negative when we're overdrawn", new ValidDollars(-333), year.endingCostBasis());
}
@Test
public void endingBalance() {
StockMarketYear year = newYear();
assertEquals("ending balance includes interest", new ValidDollars(11000), year.endingBalance());
year.sell(new ValidDollars(1000));
assertEquals("ending balance includes withdrawals (which pay capital gains tax) and interest", new ValidDollars(9533), year.endingBalance());
}
@Test
public void nextYearStartingValuesMatchesThisYearEndingValues() {
StockMarketYear thisYear = newYear();
StockMarketYear nextYear = thisYear.nextYear();
assertEquals("year", new Year(2011), nextYear.year());
assertEquals("starting balance", thisYear.endingBalance(), nextYear.startingBalance());
assertEquals("starting principal", thisYear.endingCostBasis(), nextYear.startingCostBasis());
assertEquals("interest", thisYear.growthRate(), nextYear.growthRate());
assertEquals("capital gains tax rate", thisYear.capitalGainsTaxRate(), nextYear.capitalGainsTaxRate());
}
private StockMarketYear newYear() {
return new StockMarketYear(YEAR, STARTING_BALANCE, STARTING_PRINCIPAL, INTEREST_RATE, CAPITAL_GAINS_TAX_RATE);
}
}