1 // Copyright 2020 Blue Static <https://www.bluestatic.org>
2 // This program is free software licensed under the GNU General Public License,
3 // version 3.0. The full text of the license can be found in LICENSE.txt.
4 // SPDX-License-Identifier: GPL-3.0-only
6 import { Person } from '../core';
8 import Form1040, { FilingStatus } from './Form1040';
9 import Form1099B, { Form1099BInput } from './Form1099B';
10 import Form8949, { Form8949Box, Form8949Total } from './Form8949';
11 import TaxReturn from './TaxReturn';
13 describe('single form', () => {
14 for (const box of [Form8949Box.A, Form8949Box.B, Form8949Box.D, Form8949Box.E]) {
15 test(`box ${Form8949Box[box]}`, () => {
16 const p = Person.self('A');
17 const tr = new TaxReturn();
19 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
21 const fieldMap: { [key: string]: keyof Form1099BInput } = {
22 [Form8949Box.A]: 'shortTermBasisReported',
23 [Form8949Box.B]: 'shortTermBasisUnreported',
24 [Form8949Box.C]: 'shortTermUnreported',
25 [Form8949Box.D]: 'longTermBasisReported',
26 [Form8949Box.E]: 'longTermBasisUnreported',
27 [Form8949Box.F]: 'longTermUnreported',
29 const field = fieldMap[box];
31 tr.addForm(new Form1099B({
36 description: '10 shares',
43 const form = new Form8949();
46 const allBoxes: (keyof Form8949['lines'])[] = ['boxA', 'boxB', 'boxC', 'boxD', 'boxE', 'boxF'];
47 const otherBoxes = allBoxes.filter(b => b != `box${box}`);
48 const thisBox = `box${box}` as keyof Form8949['lines'];
50 let total = form.getValue(tr, thisBox);
52 expect(total.proceeds).toBe(100);
53 expect(total.costBasis).toBe(110);
54 expect(total.adjustments).toBe(0);
55 expect(total.gainOrLoss).toBe(-10);
57 for (let otherBox of otherBoxes) {
58 total = form.getValue(tr, otherBox);
59 expect(total.proceeds).toBe(0);
60 expect(total.costBasis).toBe(0);
61 expect(total.adjustments).toBe(0);
62 expect(total.gainOrLoss).toBe(0);
68 test('multiple forms', () => {
69 const p = Person.self('A');
70 const tr = new TaxReturn();
72 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
73 tr.addForm(new Form1099B({
76 shortTermBasisReported: [
78 description: '10 SCHB',
83 longTermBasisUnreported: [
85 description: '10 SCHB',
90 description: '10 SCHF',
97 const form = new Form8949();
100 const boxA = form.getValue(tr, 'boxA');
101 expect(boxA.proceeds).toBe(55);
102 expect(boxA.costBasis).toBe(50);
103 expect(boxA.adjustments).toBe(0);
104 expect(boxA.gainOrLoss).toBe(5);
106 const boxE = form.getValue(tr, 'boxE');
107 expect(boxE.proceeds).toBe(77.40);
108 expect(boxE.costBasis).toBe(60.10);
109 expect(boxE.adjustments).toBe(0);
110 expect(boxE.gainOrLoss).toBeCloseTo(17.3);
112 const otherBoxes: (keyof Form8949['lines'])[] = ['boxB', 'boxC', 'boxD', 'boxF'];
113 for (const otherBox of otherBoxes) {
114 const other = form.getValue(tr, otherBox);
115 expect(other.proceeds).toBe(0);
116 expect(other.costBasis).toBe(0);
117 expect(other.adjustments).toBe(0);
118 expect(other.gainOrLoss).toBe(0);
122 test('adjustments', () => {
123 const p = Person.self('A');
124 const tr = new TaxReturn();
126 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
127 const b1 = new Form1099B({
130 shortTermBasisUnreported: [
132 description: '10 SCHB',
138 longTermBasisUnreported: [
140 description: '10 SCHB',
146 longTermBasisReported: [
148 description: '10 SCHF',
156 const form = new Form8949();
159 const boxB = form.getValue(tr, 'boxB');
160 expect(boxB.proceeds).toBe(55);
161 expect(boxB.costBasis).toBe(50);
162 expect(boxB.adjustments).toBe(-10);
163 expect(boxB.gainOrLoss).toBe(-5);
165 const boxE = form.getValue(tr, 'boxE');
166 expect(boxE.proceeds).toBe(18);
167 expect(boxE.costBasis).toBe(25);
168 expect(boxE.adjustments).toBe(90);
169 expect(boxE.gainOrLoss).toBe(83);
171 const boxD = form.getValue(tr, 'boxD');
172 expect(boxD.proceeds).toBe(22.40);
173 expect(boxD.costBasis).toBe(10.10);
174 expect(boxD.adjustments).toBe(0);
175 expect(boxD.gainOrLoss).toBeCloseTo(12.30);
177 const otherBoxes: (keyof Form8949['lines'])[] = ['boxA', 'boxC', 'boxF'];
178 for (const otherBox of otherBoxes) {
179 const other = form.getValue(tr, otherBox);
180 expect(other.proceeds).toBe(0);
181 expect(other.costBasis).toBe(0);
182 expect(other.adjustments).toBe(0);
183 expect(other.gainOrLoss).toBe(0);