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 { Line, AccumulatorLine, InputLine, ReferenceLine, ComputedLine } from './Line';
7 import Form, { FormClass } from './Form';
8 import TaxReturn from './TaxReturn';
9 import { NotFoundError } from './Errors';
11 class TestTaxReturn extends TaxReturn {
12 get year() { return 2019; }
13 get includeJointPersonForms() { return false; }
16 class ConstantLine<T> extends Line<T> {
20 super(`Constant ${k}`);
24 value(tr: TaxReturn): T {
29 test('computed line', () => {
30 const tr = new TestTaxReturn();
31 const l = new ComputedLine<number>(
32 (taxReturn: TaxReturn): number => {
33 expect(taxReturn).toBe(tr);
37 expect(l.value(tr)).toBe(42);
38 expect(l.description).toBe('Computed Line A');
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'),
50 const tr = new TestTaxReturn();
51 tr.addForm(new TestForm());
53 const l1 = new ReferenceLine(TestForm, '6b');
54 let n: number = l1.value(tr);
55 expect(n).toBe(12.34);
57 const l2 = new ReferenceLine(TestForm, 's');
58 let s: string = l2.value(tr);
59 expect(s).toBe('abc');
62 //const l3 = new ReferenceLine(TestForm, '7a');
63 //let n2: string = l1.value(tr);
64 //let s2: number = l2.value(tr);
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)
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'),
84 const tr = new TestTaxReturn();
85 const f = new TestForm();
87 tr.addForm(new OtherForm());
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);
95 test('input line', () => {
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')
108 const tr = new TestTaxReturn();
109 const f = new TestForm({ 'key': 'value' });
112 expect(f.getLine('1').value(tr)).toBe('value');
113 expect(f.getLine('1').id).toBe('1');
115 const l2 = f.getLine('2');
116 expect(() => l2.value(tr)).toThrow(NotFoundError);
118 expect(f.getLine('3').value(tr)).toBe('FALLBACK');
121 test('line stack', () => {
122 class FormZ extends Form<FormZ['_lines'], {'input': number}> {
124 protected readonly _lines = {
125 '3': new InputLine<any, any>('input')
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;
138 const tr = new TestTaxReturn();
139 tr.addForm(new FormZ({ 'input': 100 }));
140 tr.addForm(new FormZ2());
142 const l = new ReferenceLine(FormZ2, '2c');
143 expect(l.value(tr)).toBe(20);
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)
155 const tr = new TestTaxReturn();
156 tr.addForm(new TestForm());
157 tr.addForm(new TestForm());
158 tr.addForm(new TestForm());
160 const l = new AccumulatorLine(TestForm, 'g');
161 expect(l.value(tr)).toBe(300.75);