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