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