Split Schedule2 into its own file.
[ustaxlib.git] / src / fed2019 / Form1040.test.ts
1 import Person from '../Person';
2 import TaxReturn from '../TaxReturn';
3 import { NotFoundError } from '../Errors';
4
5 import Form1040, { FilingStatus } from './Form1040';
6 import Form1099DIV from './Form1099DIV';
7 import Form1099INT from './Form1099INT';
8 import Form1099B, { GainType } from './Form1099B';
9 import Form1099R, { Box7Code } from './Form1099R';
10 import Schedule2 from './Schedule2';
11 import ScheduleD, { ScheduleDTaxWorksheet } from './ScheduleD';
12 import Form8606 from './Form8606';
13 import Form8959 from './Form8959';
14 import Form8949 from './Form8949';
15 import FormW2 from './FormW2';
16
17 test('w2 wages', () => {
18 const pa = Person.self('A');
19 const pb = Person.spouse('B');
20 const tr = new TaxReturn(2019);
21 tr.addForm(new FormW2({
22 employer: 'AA',
23 employee: pa,
24 wages: 130000.00,
25 fedIncomeTax: 0,
26 medicareWages: 0,
27 }));
28 tr.addForm(new FormW2({
29 employer: 'BB',
30 employee: pb,
31 wages: 36.32,
32 fedIncomeTax: 0,
33 medicareWages: 0,
34 }));
35 const f1040 = new Form1040({ filingStatus: FilingStatus.MarriedFilingJoint });
36 tr.addForm(f1040);
37 tr.addForm(new Schedule2);
38 expect(f1040.getValue(tr, '1')).toBe(130036.32);
39 f1040.getValue(tr, '23');
40 });
41
42 test('interest income', () => {
43 const p = Person.self('A');
44 const tr = new TaxReturn(2019);
45 tr.addForm(new Form1099INT({
46 payer: 'Bank',
47 payee: p,
48 interest: 100,
49 taxExemptInterest: 0
50 }));
51 tr.addForm(new Form1099INT({
52 payer: 'Bank 2',
53 payee: p,
54 interest: 3.50,
55 taxExemptInterest: 95
56 }));
57
58 const f1040 = new Form1040();
59 tr.addForm(f1040);
60
61 expect(f1040.getValue(tr, '2a')).toBe(95);
62 expect(f1040.getValue(tr, '2b')).toBe(103.5);
63 });
64
65 test('dividend income', () => {
66 const p = Person.self('A');
67 const tr = new TaxReturn(2019);
68 const f1099div = new Form1099DIV({
69 payer: 'Brokerage',
70 payee: p,
71 ordinaryDividends: 100,
72 qualifiedDividends: 75,
73 totalCapitalGain: 100
74 });
75 tr.addForm(f1099div);
76 tr.addForm(f1099div);
77
78 const f1040 = new Form1040();
79 tr.addForm(f1040);
80
81 expect(f1040.getValue(tr, '3a')).toBe(75 * 2);
82 expect(f1040.getValue(tr, '3b')).toBe(200);
83 });
84
85 test('capital gain/loss', () => {
86 const p = Person.self('A');
87 const tr = new TaxReturn(2019);
88 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
89 tr.addForm(new FormW2({
90 employer: 'Money',
91 employee: p,
92 wages: 150000
93 }));
94 tr.addForm(new Form1099B({
95 payer: 'Brokerage',
96 payee: p,
97 description: '10 FNDC',
98 proceeds: 1000,
99 costBasis: 800,
100 gainType: GainType.LongTerm,
101 basisReportedToIRS: true
102 }));
103 tr.addForm(new Form8949);
104 tr.addForm(new ScheduleD());
105 tr.addForm(new ScheduleDTaxWorksheet());
106 tr.getForm(ScheduleD).getValue(tr, '21');
107 tr.getForm(Form1040).getValue(tr, '12a');
108 });
109
110 test('require Form8959', () => {
111 const p = Person.self('A');
112 const tr = new TaxReturn(2019);
113 tr.addForm(new FormW2({
114 employer: 'Company',
115 employee: p,
116 wages: 400000,
117 }));
118 const f1040 = new Form1040({
119 filingStatus: FilingStatus.MarriedFilingSeparate,
120 });
121 tr.addForm(f1040);
122 tr.addForm(new Schedule2);
123
124 expect(() => f1040.getValue(tr, '15')).toThrow(NotFoundError);
125 expect(() => f1040.getValue(tr, '15')).toThrow('Form8959');
126 expect(f1040.getValue(tr, '1')).toBe(400000);
127 expect(f1040.getValue(tr, '8b')).toBe(400000);
128 });
129
130 test('backdoor and megabackdoor roth', () => {
131 const p = Person.self('A');
132 const tr = new TaxReturn(2019);
133 tr.addForm(new Form1099R({
134 payer: 'Roth',
135 payee: p,
136 grossDistribution: 6000,
137 taxableAmount: 6000,
138 taxableAmountNotDetermined: true,
139 totalDistribution: true,
140 fedIncomeTax: 0,
141 distributionCodes: [Box7Code._2],
142 iraSepSimple: true
143 }));
144 tr.addForm(new Form1099R({
145 payer: '401k',
146 payee: p,
147 grossDistribution: 27500,
148 taxableAmount: 0,
149 taxableAmountNotDetermined: false,
150 totalDistribution: false,
151 fedIncomeTax: 0,
152 employeeContributionsOrDesignatedRothContributions: 27500,
153 distributionCodes: [Box7Code.G],
154 iraSepSimple: false
155 }));
156 tr.addForm(new Form8606({
157 person: p,
158 nondeductibleContributions: 6000,
159 traditionalIraBasis: 0,
160 distributionFromTradSepOrSimpleIraOrMadeRothConversion: true,
161 contributionsMadeInCurrentYear: 0,
162 distributionsFromAllTradSepSimpleIras: 0,
163 valueOfAllTradSepSimpleIras: 0,
164 amountConvertedFromTradSepSimpleToRoth: 6000
165 }));
166 const f = new Form1040();
167 tr.addForm(f);
168
169 expect(f.getValue(tr, '4a')).toBe(6000);
170 expect(f.getValue(tr, '4b')).toBe(0);
171 });