This also associates every Line to a Form.
expect(() => new TestForm()).toThrow(InconsistencyError);
});
+
+test('add line to two forms', () => {
+ const l = new ComputedLine<string>('bad', () => 'bad');
+
+ class TestForm1 extends Form {
+ get name(): string { return '1'; }
+
+ protected getLines() { return [ l ]; }
+ };
+ class TestForm2 extends Form {
+ get name(): string { return '2'; }
+
+ protected getLines() { return [ l ]; }
+ };
+
+ const f1 = new TestForm1();
+ expect(() => new TestForm2()).toThrow(InconsistencyError);
+});
+
+test('input', () => {
+ class TestForm extends Form {
+ get name() { return '1040'; }
+
+ protected getLines() { return []; }
+ };
+ const f = new TestForm({ 'Filing Status': 'S' });
+ expect(f.getInput('Filing Status')).toBe('S');
+ expect(() => f.getInput('Unknown')).toThrow(NotFoundError);
+});
export default abstract class Form {
private _lines: Line<any>[] = [];
+ private _input?: object;
abstract get name(): string;
- constructor() {
+ constructor(input?: object) {
+ this._input = input;
this.getLines().map(this.addLine.bind(this));
}
}
private addLine(line: Line<any>) {
+ if (line.form !== undefined) {
+ throw new InconsistencyError('Line is already in a Form');
+ }
try {
this.getLine(line.id);
} catch {
+ line.form = this;
this._lines.push(line);
return;
}
}
return lines[0];
}
+
+ getInput<T>(name: string): T {
+ if (!(name in this._input)) {
+ throw new NotFoundError(`No input with key ${name} on form ${this.name}`);
+ }
+ return this._input[name] as T;
+ }
};
});
test('input line', () => {
- const tr = new TaxReturn(2019, { 'key': 'value' });
+ class TestForm extends Form {
+ get name() { return 'F1'; }
- const l1 = new InputLine<string>('1', 'key');
- expect(l1.value(tr)).toBe('value');
+ protected getLines() {
+ return [
+ new InputLine<string>('1', 'key'),
+ new InputLine<string>('2', 'key2')
+ ];
+ }
+ };
+ const tr = new TaxReturn(2019);
+ const f = new TestForm({ 'key': 'value' });
- const l2 = new InputLine<string>('2', 'key2');
+ expect(f.getLine('1').value(tr)).toBe('value');
+
+ const l2 = f.getLine('2');
expect(() => l2.value(tr)).toThrow(NotFoundError);
});
}
};
- const tr = new TaxReturn(2019, { 'input': 100 });
- tr.addForm(new FormZ());
+ const tr = new TaxReturn(2019);
+ tr.addForm(new FormZ({ 'input': 100 }));
tr.addForm(new FormZ2());
const l = new ReferenceLine<number>('32', 'Z-2', '2c');
import TaxReturn from './TaxReturn';
+import Form from './Form';
export abstract class Line<T> {
private _id: string;
private _description?: string;
+ form: Form;
+
constructor(id: string, description?: string) {
this._id = id;
this._description = description;
}
value(tr: TaxReturn): T {
- return tr.getInput<T>(this._input);
+ return this.form.getInput<T>(this._input);
}
};
expect(() => tr.getForm('form')).toThrow(NotFoundError);
expect(tr.getForms('form')).toEqual([]);
});
-
-test('input', () => {
- const tr = new TaxReturn(2019, { 'Filing Status': 'S' });
- expect(tr.getInput('Filing Status')).toBe('S');
- expect(() => tr.getInput('Unknown')).toThrow(NotFoundError);
-});
export default class TaxReturn {
private _year: number;
- private _input: object;
private _people: Person[] = [];
private _forms: Form[] = [];
- constructor(year: number, input?: object) {
+ constructor(year: number) {
this._year = year;
- this._input = input;
}
get year(): number {
return this._year;
}
- getInput<T>(name: string): T {
- if (!(name in this._input)) {
- throw new NotFoundError(`No input with key ${name}`);
- }
- return this._input[name] as T;
- }
-
addPerson(person: Person) {
if (person.relation == Relation.Dependent) {
throw new UnsupportedFeatureError('Dependents are not supported');