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';
7 import { NotFoundError } from '../core/Errors';
9 import Form1040, { FilingStatus } from './Form1040';
10 import Form1099DIV from './Form1099DIV';
11 import Form1099INT from './Form1099INT';
12 import Form1099B, { GainType } from './Form1099B';
13 import Form1099R, { Box7Code } from './Form1099R';
14 import Schedule2 from './Schedule2';
15 import ScheduleD, { ScheduleDTaxWorksheet } from './ScheduleD';
16 import Form8606 from './Form8606';
17 import Form8959 from './Form8959';
18 import Form8949 from './Form8949';
19 import TaxReturn from './TaxReturn';
20 import W2 from './W2';
22 test('w2 wages', () => {
23 const pa = Person.self('A');
24 const pb = Person.spouse('B');
25 const tr = new TaxReturn();
42 const f1040 = new Form1040({ filingStatus: FilingStatus.MarriedFilingJoint });
44 tr.addForm(new Schedule2);
45 expect(f1040.getValue(tr, '1')).toBe(130036.32);
46 f1040.getValue(tr, '23');
49 test('interest income', () => {
50 const p = Person.self('A');
51 const tr = new TaxReturn();
53 tr.addForm(new Form1099INT({
58 interestOnUsSavingsBondOrTreas: 30
60 tr.addForm(new Form1099INT({
67 const f1040 = new Form1040();
70 expect(f1040.getValue(tr, '2a')).toBe(95);
71 expect(f1040.getValue(tr, '2b')).toBe(133.5);
74 test('dividend income', () => {
75 const p = Person.self('A');
76 const tr = new TaxReturn();
78 const f1099div = new Form1099DIV({
81 ordinaryDividends: 100,
82 qualifiedDividends: 75,
88 const f1040 = new Form1040();
91 expect(f1040.getValue(tr, '3a')).toBe(75 * 2);
92 expect(f1040.getValue(tr, '3b')).toBe(200);
95 test('tax-exempt interest', () => {
96 const p = Person.self('A');
97 const tr = new TaxReturn();
99 tr.addForm(new Form1099DIV({
102 exemptInterestDividends: 100,
104 tr.addForm(new Form1099INT({
108 taxExemptInterest: 50
111 const f1040 = new Form1040();
114 expect(f1040.getValue(tr, '2a')).toBe(150);
117 test('capital gain/loss', () => {
118 const p = Person.self('A');
119 const tr = new TaxReturn();
121 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
127 tr.addForm(new Form1099B({
130 description: '10 FNDC',
133 gainType: GainType.LongTerm,
134 basisReportedToIRS: true
136 tr.addForm(new Form8949);
137 tr.addForm(new ScheduleD());
138 tr.addForm(new ScheduleDTaxWorksheet());
139 tr.getForm(ScheduleD).getValue(tr, '21');
140 tr.getForm(Form1040).getValue(tr, '12a');
143 test('require Form8959', () => {
144 const p = Person.self('A');
145 const tr = new TaxReturn();
152 const f1040 = new Form1040({
153 filingStatus: FilingStatus.MarriedFilingSeparate,
156 tr.addForm(new Schedule2);
158 expect(() => f1040.getValue(tr, '15')).toThrow(NotFoundError);
159 expect(() => f1040.getValue(tr, '15')).toThrow('Form8959');
160 expect(f1040.getValue(tr, '1')).toBe(400000);
161 expect(f1040.getValue(tr, '8b')).toBe(400000);
164 test('backdoor and megabackdoor roth', () => {
165 const p = Person.self('A');
166 const tr = new TaxReturn();
168 tr.addForm(new Form1099R({
171 grossDistribution: 6000,
173 taxableAmountNotDetermined: true,
174 totalDistribution: true,
176 distributionCodes: [Box7Code._2],
179 tr.addForm(new Form1099R({
182 grossDistribution: 27500,
184 taxableAmountNotDetermined: false,
185 totalDistribution: false,
187 employeeContributionsOrDesignatedRothContributions: 27500,
188 distributionCodes: [Box7Code.G],
191 tr.addForm(new Form8606({
193 nondeductibleContributions: 6000,
194 traditionalIraBasis: 0,
195 distributionFromTradSepOrSimpleIraOrMadeRothConversion: true,
196 contributionsMadeInCurrentYear: 0,
197 distributionsFromAllTradSepSimpleIras: 0,
198 valueOfAllTradSepSimpleIras: 0,
199 amountConvertedFromTradSepSimpleToRoth: 6000
201 const f = new Form1040();
204 expect(f.getValue(tr, '4a')).toBe(6000);
205 expect(f.getValue(tr, '4b')).toBe(0);