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