Use the original idea for Form8949, which is simpler.
[ustaxlib.git] / src / fed2019 / Form8949.test.ts
1 import TaxReturn from '../TaxReturn';
2 import Person from '../Person';
3
4 import Form1040, { FilingStatus } from './Form1040';
5 import Form1099B, { GainType } from './Form1099B';
6 import Form8949, { Form8949Box, Form8949Total } from './Form8949';
7
8 describe('single form', () => {
9 for (const box of [Form8949Box.A, Form8949Box.B, Form8949Box.D, Form8949Box.E]) {
10 test(`box ${Form8949Box[box]}`, () => {
11 const p = Person.self('A');
12 const tr = new TaxReturn(2019);
13 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
14 tr.addForm(new Form1099B({
15 payer: 'Brokerage',
16 payee: p,
17 description: '10 shares',
18 proceeds: 100,
19 costBasis: 110,
20 gainType: (box == Form8949Box.A || box == Form8949Box.B) ? GainType.ShortTerm : GainType.LongTerm,
21 basisReportedToIRS: (box == Form8949Box.A || box == Form8949Box.D),
22 }));
23
24 const form = new Form8949();
25 tr.addForm(form);
26
27 const allBoxes: (keyof Form8949['lines'])[] = ['boxA', 'boxB', 'boxC', 'boxD', 'boxE', 'boxF'];
28 const otherBoxes = allBoxes.filter(b => b != `box${box}`);
29 const thisBox = `box${box}` as keyof Form8949['lines'];
30
31 let total = form.getValue(tr, thisBox);
32
33 expect(total.proceeds).toBe(100);
34 expect(total.costBasis).toBe(110);
35 expect(total.adjustments).toBe(0);
36 expect(total.gainOrLoss).toBe(-10);
37
38 for (let otherBox of otherBoxes) {
39 total = form.getValue(tr, otherBox);
40 expect(total.proceeds).toBe(0);
41 expect(total.costBasis).toBe(0);
42 expect(total.adjustments).toBe(0);
43 expect(total.gainOrLoss).toBe(0);
44 }
45 });
46 }
47 });
48
49 test('multiple forms', () => {
50 const p = Person.self('A');
51 const tr = new TaxReturn(2019);
52 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
53 tr.addForm(new Form1099B({
54 payer: 'Brokerage',
55 payee: p,
56 description: '10 SCHB',
57 proceeds: 55,
58 costBasis: 50,
59 gainType: GainType.ShortTerm,
60 basisReportedToIRS: true,
61 }));
62 tr.addForm(new Form1099B({
63 payer: 'Brokerage',
64 payee: p,
65 description: '10 SCHB',
66 proceeds: 55,
67 costBasis: 50,
68 gainType: GainType.LongTerm,
69 basisReportedToIRS: false,
70 }));
71 tr.addForm(new Form1099B({
72 payer: 'Brokerage',
73 payee: p,
74 description: '10 SCHF',
75 proceeds: 22.40,
76 costBasis: 10.10,
77 gainType: GainType.LongTerm,
78 basisReportedToIRS: false,
79 }));
80
81 const form = new Form8949();
82 tr.addForm(form);
83
84 const boxA = form.getValue(tr, 'boxA');
85 expect(boxA.proceeds).toBe(55);
86 expect(boxA.costBasis).toBe(50);
87 expect(boxA.adjustments).toBe(0);
88 expect(boxA.gainOrLoss).toBe(5);
89
90 const boxE = form.getValue(tr, 'boxE');
91 expect(boxE.proceeds).toBe(77.40);
92 expect(boxE.costBasis).toBe(60.10);
93 expect(boxE.adjustments).toBe(0);
94 expect(boxE.gainOrLoss).toBeCloseTo(17.3);
95
96 const otherBoxes: (keyof Form8949['lines'])[] = ['boxB', 'boxC', 'boxD', 'boxF'];
97 for (const otherBox of otherBoxes) {
98 const other = form.getValue(tr, otherBox);
99 expect(other.proceeds).toBe(0);
100 expect(other.costBasis).toBe(0);
101 expect(other.adjustments).toBe(0);
102 expect(other.gainOrLoss).toBe(0);
103 }
104 });
105
106 test('adjustments', () => {
107 const p = Person.self('A');
108 const tr = new TaxReturn(2019);
109 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
110 const b1 = new Form1099B({
111 payer: 'Brokerage',
112 payee: p,
113 description: '10 SCHB',
114 proceeds: 55,
115 costBasis: 50,
116 gainType: GainType.ShortTerm,
117 basisReportedToIRS: false,
118 });
119 tr.addForm(b1);
120 const b2 = new Form1099B({
121 payer: 'Brokerage',
122 payee: p,
123 description: '10 SCHB',
124 proceeds: 18,
125 costBasis: 25,
126 gainType: GainType.LongTerm,
127 basisReportedToIRS: false,
128 });
129 tr.addForm(b2);
130 tr.addForm(new Form1099B({
131 payer: 'Brokerage',
132 payee: p,
133 description: '10 SCHF',
134 proceeds: 22.40,
135 costBasis: 10.10,
136 gainType: GainType.LongTerm,
137 basisReportedToIRS: true,
138 }));
139
140 const form = new Form8949({
141 adjustments: [
142 { entry: b1, code: 'W', amount: -10 },
143 { entry: b2, code: 'W', amount: 90 },
144 ]
145 });
146 tr.addForm(form);
147
148 const boxB = form.getValue(tr, 'boxB');
149 expect(boxB.proceeds).toBe(55);
150 expect(boxB.costBasis).toBe(50);
151 expect(boxB.adjustments).toBe(-10);
152 expect(boxB.gainOrLoss).toBe(-5);
153
154 const boxE = form.getValue(tr, 'boxE');
155 expect(boxE.proceeds).toBe(18);
156 expect(boxE.costBasis).toBe(25);
157 expect(boxE.adjustments).toBe(90);
158 expect(boxE.gainOrLoss).toBe(83);
159
160 const boxD = form.getValue(tr, 'boxD');
161 expect(boxD.proceeds).toBe(22.40);
162 expect(boxD.costBasis).toBe(10.10);
163 expect(boxD.adjustments).toBe(0);
164 expect(boxD.gainOrLoss).toBeCloseTo(12.30);
165
166 const otherBoxes: (keyof Form8949['lines'])[] = ['boxA', 'boxC', 'boxF'];
167 for (const otherBox of otherBoxes) {
168 const other = form.getValue(tr, otherBox);
169 expect(other.proceeds).toBe(0);
170 expect(other.costBasis).toBe(0);
171 expect(other.adjustments).toBe(0);
172 expect(other.gainOrLoss).toBe(0);
173 }
174 });