Extract constant values from fed2019 Forms as named definitions.
[ustaxlib.git] / src / core / Line.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 { Line, AccumulatorLine, InputLine, ReferenceLine, ComputedLine } from './Line';
7 import Form, { FormClass } from './Form';
8 import TaxReturn from './TaxReturn';
9 import { NotFoundError } from './Errors';
10
11 class TestTaxReturn extends TaxReturn {
12 readonly constants = undefined;
13 get year() { return 2019; }
14 get includeJointPersonForms() { return false; }
15 };
16
17 class ConstantLine<T> extends Line<T> {
18 private _k: T;
19
20 constructor(k: T) {
21 super(`Constant ${k}`);
22 this._k = k;
23 }
24
25 value(tr: TaxReturn): T {
26 return this._k;
27 }
28 };
29
30 test('computed line', () => {
31 const tr = new TestTaxReturn();
32 const l = new ComputedLine<number>(
33 (taxReturn: TaxReturn): number => {
34 expect(taxReturn).toBe(tr);
35 return 42;
36 },
37 'Computed Line A');
38 expect(l.value(tr)).toBe(42);
39 expect(l.description).toBe('Computed Line A');
40 });
41
42 test('reference line', () => {
43 class TestForm extends Form {
44 readonly name = 'Form 1';
45 readonly lines = {
46 '6b': new ConstantLine(12.34),
47 's': new ConstantLine('abc'),
48 };
49 };
50
51 const tr = new TestTaxReturn();
52 tr.addForm(new TestForm());
53
54 const l1 = new ReferenceLine(TestForm, '6b');
55 let n: number = l1.value(tr);
56 expect(n).toBe(12.34);
57
58 const l2 = new ReferenceLine(TestForm, 's');
59 let s: string = l2.value(tr);
60 expect(s).toBe('abc');
61
62 //TYPEERROR:
63 //const l3 = new ReferenceLine(TestForm, '7a');
64 //let n2: string = l1.value(tr);
65 //let s2: number = l2.value(tr);
66 });
67
68 test('self reference line', () => {
69 class OtherForm extends Form {
70 readonly name = 'Form A';
71 readonly lines = {
72 '6c': new ConstantLine(55)
73 };
74 };
75 class TestForm extends Form {
76 readonly name = 'Form 1';
77 readonly lines = {
78 'a': new ConstantLine(100.2),
79 'b': new ReferenceLine(OtherForm, '6c'),
80 'c': new ReferenceLine((TestForm as unknown) as FormClass<Form>, 'b'),
81 'd': new ReferenceLine(TestForm as any, 'b'),
82 };
83 };
84
85 const tr = new TestTaxReturn();
86 const f = new TestForm();
87 tr.addForm(f);
88 tr.addForm(new OtherForm());
89
90 expect(f.getValue(tr, 'a')).toBe(100.2);
91 expect(f.getValue(tr, 'b')).toBe(55);
92 expect(f.getValue(tr, 'c')).toBe(55);
93 expect(f.getValue(tr, 'd')).toBe(55);
94 });
95
96 test('input line', () => {
97 interface Input {
98 key: string;
99 key2?: string;
100 }
101 class TestForm extends Form<Input> {
102 readonly name = 'F1';
103 readonly lines = {
104 '1': new InputLine<Input>('key'),
105 '2': new InputLine<Input>('key2'),
106 '3': new InputLine<Input>('key2', undefined, 'FALLBACK')
107 };
108 };
109 const tr = new TestTaxReturn();
110 const f = new TestForm({ 'key': 'value' });
111 tr.addForm(f);
112
113 expect(f.getLine('1').value(tr)).toBe('value');
114 expect(f.getLine('1').id).toBe('1');
115
116 const l2 = f.getLine('2');
117 expect(() => l2.value(tr)).toThrow(NotFoundError);
118
119 expect(f.getLine('3').value(tr)).toBe('FALLBACK');
120 });
121
122 test('line stack', () => {
123 class FormZ extends Form<{'input': number}> {
124 readonly name = 'Z';
125 readonly lines = {
126 '3': new InputLine<any, any>('input')
127 }
128 };
129
130 class FormZ2 extends Form {
131 readonly name = 'Z-2';
132 readonly lines = {
133 '2c': new ComputedLine<number>((tr: TaxReturn): any => {
134 return tr.getForm(FormZ).getLine('3').value(tr) * 0.2;
135 })
136 };
137 };
138
139 const tr = new TestTaxReturn();
140 tr.addForm(new FormZ({ 'input': 100 }));
141 tr.addForm(new FormZ2());
142
143 const l = new ReferenceLine(FormZ2, '2c');
144 expect(l.value(tr)).toBe(20);
145 });
146
147 test('accumulator line', () => {
148 class TestForm extends Form {
149 readonly name = 'Form B';
150 readonly supportsMultipleCopies = true;
151 readonly lines = {
152 g: new ConstantLine<number>(100.25)
153 };
154 };
155
156 const tr = new TestTaxReturn();
157 tr.addForm(new TestForm());
158 tr.addForm(new TestForm());
159 tr.addForm(new TestForm());
160
161 const l = new AccumulatorLine(TestForm, 'g');
162 expect(l.value(tr)).toBe(300.75);
163 });