Add license information.
[ustaxlib.git] / src / fed2019 / Form1116.test.ts
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
5
6 import { Person } from '../core';
7 import { UnsupportedFeatureError } from '../core/Errors';
8
9 import Form1040, { FilingStatus } from './Form1040';
10 import Form1116, { ForeignIncomeCategory } from './Form1116';
11 import Form1099B, { GainType } from './Form1099B';
12 import Form1099DIV from './Form1099DIV';
13 import Form8949 from './Form8949';
14 import W2 from './W2';
15 import TaxReturn from './TaxReturn';
16 import ScheduleD from './ScheduleD';
17
18 test('supported income category', () => {
19 const p = Person.self('A');
20 const tr = new TaxReturn();
21 const f = new Form1116({
22 person: p,
23 incomeCategory: ForeignIncomeCategory.C,
24 posessionName: "RIC",
25 grossForeignIncome: 100,
26 totalForeignTaxesPaidOrAccrued: 0
27 });
28 tr.addForm(f);
29 expect(f.getValue(tr, 'category')).toBe(ForeignIncomeCategory.C);
30 });
31
32 test('unsupported income categories', () => {
33 for (const category of Object.values(ForeignIncomeCategory)) {
34 if (category == ForeignIncomeCategory.C)
35 continue;
36
37 const p = Person.self('B');
38 const tr = new TaxReturn();
39 const f = new Form1116({
40 person: p,
41 incomeCategory: category,
42 posessionName: "RIC",
43 grossForeignIncome: 100,
44 totalForeignTaxesPaidOrAccrued: 0
45 });
46 tr.addForm(f);
47 expect(() => f.getValue(tr, 'category')).toThrow(UnsupportedFeatureError);
48 }
49 });
50
51 test('foreign tax credit', () => {
52 const p = Person.self('A');
53 const tr = new TaxReturn();
54 tr.addForm(new Form1040({
55 filingStatus: FilingStatus.MarriedFilingJoint
56 }));
57 tr.addForm(new W2({
58 employer: 'ACME',
59 employee: p,
60 wages: 697000,
61 }));
62
63 const f = new Form1116({
64 person: p,
65 incomeCategory: ForeignIncomeCategory.C,
66 posessionName: "RIC",
67 grossForeignIncome: 99,
68 totalForeignTaxesPaidOrAccrued: 14
69 });
70 tr.addForm(f);
71
72 expect(f.getValue(tr, '1a')).toBe(99);
73 expect(f.getValue(tr, '3a')).toBe(24400);
74 expect(f.getValue(tr, '3c')).toBe(24400);
75 expect(f.getValue(tr, '3d')).toBe(99);
76 expect(f.getValue(tr, '3e')).toBe(697000);
77 expect(f.getValue(tr, '3f')).toBe(0.0001);
78 expect(f.getValue(tr, '3g')).toBeCloseTo(2.44);
79 expect(f.getValue(tr, '6')).toBeCloseTo(2.44);
80 expect(f.getValue(tr, '7')).toBeCloseTo(96.56);
81 expect(f.getValue(tr, '8')).toBe(14);
82 expect(f.getValue(tr, '9')).toBe(14);
83 expect(f.getValue(tr, '14')).toBe(14);
84 expect(f.getValue(tr, '20')).toBe(((697000-24400) * 0.37) - 61860);
85 expect(f.getValue(tr, '21')).toBeCloseTo(26.846);
86 expect(f.getValue(tr, '22')).toBe(14);
87 expect(f.getValue(tr, '31')).toBe(14);
88 expect(f.getValue(tr, '33')).toBe(14);
89 });
90
91 test('no net capital losses in total income', () => {
92 const p = Person.self('A');
93 const tr = new TaxReturn();
94 tr.addPerson(p);
95 tr.addForm(new Form1040({
96 filingStatus: FilingStatus.MarriedFilingJoint
97 }));
98 tr.addForm(new W2({
99 employer: 'Megacorp',
100 employee: p,
101 wages: 200000
102 }));
103 tr.addForm(new Form1099B({
104 payer: 'Brokerage',
105 payee: p,
106 description: 'SCHF',
107 proceeds: 100,
108 costBasis: 50,
109 gainType: GainType.LongTerm,
110 basisReportedToIRS: true
111 }));
112 tr.addForm(new Form1099B({
113 payer: 'Brokerage',
114 payee: p,
115 description: 'SCHE',
116 proceeds: 60,
117 costBasis: 100,
118 gainType: GainType.ShortTerm,
119 basisReportedToIRS: true
120 }));
121 tr.addForm(new Form8949);
122 tr.addForm(new ScheduleD);
123
124 const f = new Form1116({
125 person: p,
126 incomeCategory: ForeignIncomeCategory.C,
127 posessionName: 'RIC',
128 grossForeignIncome: 200,
129 totalForeignTaxesPaidOrAccrued: 65
130 });
131
132 expect(tr.getForm(Form8949).getValue(tr, 'boxA').gainOrLoss).toBe(-40);
133 expect(tr.getForm(Form8949).getValue(tr, 'boxD').gainOrLoss).toBe(50);
134 expect(f.getValue(tr, '3e')).toBe(200050);
135 });