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 from './Form1099B';
13 import Form1099R, { Box7Code } from './Form1099R';
14 import Schedule2 from './Schedule2';
15 import ScheduleA from './ScheduleA';
16 import ScheduleD, { ScheduleDTaxWorksheet } from './ScheduleD';
17 import Form8606 from './Form8606';
18 import Form8959 from './Form8959';
19 import Form8949 from './Form8949';
20 import TaxReturn from './TaxReturn';
21 import W2 from './W2';
23 test('w2 wages', () => {
24 const pa = Person.self('A');
25 const pb = Person.spouse('B');
26 const tr = new TaxReturn();
43 const f1040 = new Form1040({ filingStatus: FilingStatus.MarriedFilingJoint });
45 tr.addForm(new Schedule2);
46 expect(f1040.getValue(tr, '1')).toBe(130036.32);
47 f1040.getValue(tr, '23');
50 test('interest income', () => {
51 const p = Person.self('A');
52 const tr = new TaxReturn();
54 tr.addForm(new Form1099INT({
59 interestOnUsSavingsBondOrTreas: 30
61 tr.addForm(new Form1099INT({
68 const f1040 = new Form1040();
71 expect(f1040.getValue(tr, '2a')).toBe(95);
72 expect(f1040.getValue(tr, '2b')).toBe(133.5);
75 test('dividend income', () => {
76 const p = Person.self('A');
77 const tr = new TaxReturn();
79 const f1099div = new Form1099DIV({
82 ordinaryDividends: 100,
83 qualifiedDividends: 75,
89 const f1040 = new Form1040();
92 expect(f1040.getValue(tr, '3a')).toBe(75 * 2);
93 expect(f1040.getValue(tr, '3b')).toBe(200);
96 test('tax-exempt interest', () => {
97 const p = Person.self('A');
98 const tr = new TaxReturn();
100 tr.addForm(new Form1099DIV({
103 exemptInterestDividends: 100,
105 tr.addForm(new Form1099INT({
109 taxExemptInterest: 50
112 const f1040 = new Form1040();
115 expect(f1040.getValue(tr, '2a')).toBe(150);
118 test('capital gain/loss', () => {
119 const p = Person.self('A');
120 const tr = new TaxReturn();
122 tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
128 tr.addForm(new Form1099B({
131 longTermBasisReported: [
133 description: '10 FNDC',
139 tr.addForm(new Form8949);
140 tr.addForm(new ScheduleD());
141 tr.addForm(new ScheduleDTaxWorksheet());
142 tr.getForm(ScheduleD).getValue(tr, '21');
143 tr.getForm(Form1040).getValue(tr, '12a');
146 test('require Form8959', () => {
147 const p = Person.self('A');
148 const tr = new TaxReturn();
155 const f1040 = new Form1040({
156 filingStatus: FilingStatus.MarriedFilingSeparate,
159 tr.addForm(new Schedule2);
161 expect(() => f1040.getValue(tr, '15')).toThrow(NotFoundError);
162 expect(() => f1040.getValue(tr, '15')).toThrow('Form8959');
163 expect(f1040.getValue(tr, '1')).toBe(400000);
164 expect(f1040.getValue(tr, '8b')).toBe(400000);
167 test('backdoor and megabackdoor roth', () => {
168 const p = Person.self('A');
169 const tr = new TaxReturn();
171 tr.addForm(new Form1099R({
174 grossDistribution: 6000,
176 taxableAmountNotDetermined: true,
177 totalDistribution: true,
179 distributionCodes: [Box7Code._2],
182 tr.addForm(new Form1099R({
185 grossDistribution: 27500,
187 taxableAmountNotDetermined: false,
188 totalDistribution: false,
190 employeeContributionsOrDesignatedRothContributions: 27500,
191 distributionCodes: [Box7Code.G],
194 tr.addForm(new Form8606({
196 nondeductibleContributions: 6000,
197 traditionalIraBasis: 0,
198 distributionFromTradSepOrSimpleIraOrMadeRothConversion: true,
199 contributionsMadeInCurrentYear: 0,
200 distributionsFromAllTradSepSimpleIras: 0,
201 valueOfAllTradSepSimpleIras: 0,
202 amountConvertedFromTradSepSimpleToRoth: 6000
204 const f = new Form1040();
207 expect(f.getValue(tr, '4a')).toBe(6000);
208 expect(f.getValue(tr, '4b')).toBe(0);
211 test('itemized deductions', () => {
212 const tr = new TaxReturn();
213 const f = new Form1040({
214 filingStatus: FilingStatus.MarriedFilingJoint
217 tr.addForm(new ScheduleA({
218 charitableGiftsCashOrCheck: 26000
221 expect(f.getValue(tr, '9')).toBe(26000);
224 test('itemized deductions, forced', () => {
225 const tr = new TaxReturn();
226 const f = new Form1040({
227 filingStatus: FilingStatus.MarriedFilingJoint
230 tr.addForm(new ScheduleA({
231 stateAndLocalIncomeAndSalesTaxes: 10000,
235 expect(f.getValue(tr, '9')).toBe(10000);