@barchart/portfolio-api-common 1.10.0 → 1.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/formatters/TransactionFormatter.js +54 -2
- package/lib/processing/PositionGroup.js +5 -5
- package/package.json +1 -1
- package/.jshintrc +0 -6
- package/.releases/1.10.0.md +0 -3
- package/.releases/1.5.0.md +0 -3
- package/.releases/1.5.1.md +0 -3
- package/.releases/1.5.2.md +0 -4
- package/.releases/1.6.0.md +0 -3
- package/.releases/1.7.0.md +0 -3
- package/.releases/1.8.0.md +0 -3
- package/.releases/1.9.0.md +0 -4
- package/.releases/1.9.1.md +0 -4
- package/buildspec.yml +0 -15
- package/gulpfile.js +0 -122
- package/test/SpecRunner.js +0 -18638
- package/test/SpecRunnner.html +0 -19
- package/test/specs/data/PositionSummaryFrameSpec.js +0 -629
- package/test/specs/data/TransactionValidatorSpec.js +0 -94
- package/test/specs/processing/PositionContainerSpec.js +0 -185
- package/test/specs/serialization/PositionSchemaSpec.js +0 -64
- package/test/specs/serialization/TransactionSchemaSpec.js +0 -65
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const Day = require('@barchart/common-js/lang/Day');
|
|
2
|
-
|
|
3
|
-
const TransactionType = require('./../../../lib/data/TransactionType'),
|
|
4
|
-
TransactionValidator = require('./../../../lib/data/TransactionValidator');
|
|
5
|
-
|
|
6
|
-
describe('When validating transaction order', () => {
|
|
7
|
-
'use strict';
|
|
8
|
-
|
|
9
|
-
const build = (sequence, day, type) => {
|
|
10
|
-
return { sequence: sequence, date: Day.parse(day), type: (type || TransactionType.BUY) };
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
it('An array of zero transactions should be valid', () => {
|
|
14
|
-
expect(TransactionValidator.validateOrder([])).toEqual(true);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('An array of transactions with ordered sequences, on the same day should be valid', () => {
|
|
18
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-04-30'), build(3, '2018-04-30') ])).toEqual(true);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs last, should be valid', () => {
|
|
22
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-04-30', TransactionType.DIVIDEND) ])).toEqual(true);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in strict mode, should not be valid', () => {
|
|
26
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], true)).toEqual(false);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('An array of transactions with ordered sequences, on the same day should be valid, where a dividend occurs first, in non-strict mode, should be valid', () => {
|
|
30
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30', TransactionType.DIVIDEND), build(2, '2018-04-30') ], false)).toEqual(true);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('An array of transactions with ordered sequences, on the sequential days should be valid', () => {
|
|
34
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(2, '2018-05-01'), build(3, '2018-05-02', TransactionType.DIVIDEND) ])).toEqual(true);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('An array of transactions with ordered sequences (starting after one), on the same day should not be valid', () => {
|
|
38
|
-
expect(TransactionValidator.validateOrder([ build(3, '2018-04-30'), build(4, '2018-04-30'), build(5, '2018-04-30') ])).toEqual(false);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('An array of transactions with duplicate sequences, on the same day should not be valid', () => {
|
|
42
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(1, '2018-04-30') ])).toEqual(false);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('An array of transactions with with a gap in sequences, on the same day should not be valid', () => {
|
|
46
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-04-30'), build(3, '2018-04-30') ])).toEqual(false);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('An array of transactions with with a reversed sequences, on the same subsequent days should not be valid', () => {
|
|
50
|
-
expect(TransactionValidator.validateOrder([ build(2, '2018-04-30'), build(1, '2018-05-01') ])).toEqual(false);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('An array of transactions with ordered sequences, on the reversed days should not be valid', () => {
|
|
54
|
-
expect(TransactionValidator.validateOrder([ build(1, '2018-05-02'), build(2, '2018-05-01'), build(3, '2018-04-30') ])).toEqual(false);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('When validating transaction references', () => {
|
|
59
|
-
'use strict';
|
|
60
|
-
|
|
61
|
-
const build = (root, transaction) => {
|
|
62
|
-
return { reference: { root: root, transaction: transaction } };
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
it('An array of zero transactions should be valid', () => {
|
|
66
|
-
expect(TransactionValidator.validateReferences([])).toEqual(true);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('An array with no references should be valid', () => {
|
|
70
|
-
expect(TransactionValidator.validateReferences([ { }, { } ])).toEqual(true);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('An array with distinct references should be valid', () => {
|
|
74
|
-
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'y') ])).toEqual(true);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('An array with non-distinct references should be not valid', () => {
|
|
78
|
-
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'x'), build('a', 'y') ])).toEqual(false);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('When requesting all the user-initiated transaction types', () => {
|
|
83
|
-
'use strict';
|
|
84
|
-
|
|
85
|
-
let userInitiated;
|
|
86
|
-
|
|
87
|
-
beforeEach(() => {
|
|
88
|
-
userInitiated = TransactionValidator.getUserInitiatedTransactionTypes();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('Only nine types should be returned', () => {
|
|
92
|
-
expect(userInitiated.length).toEqual(9);
|
|
93
|
-
});
|
|
94
|
-
});
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
const Currency = require('@barchart/common-js/lang/Currency'),
|
|
2
|
-
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
3
|
-
|
|
4
|
-
const InstrumentType = require('./../../../lib/data/InstrumentType'),
|
|
5
|
-
PositionSummaryFrame = require('./../../../lib/data/PositionSummaryFrame');
|
|
6
|
-
|
|
7
|
-
const PositionContainer = require('./../../../lib/processing/PositionContainer'),
|
|
8
|
-
PositionLevelDefinition = require('./../../../lib/processing/definitions/PositionLevelDefinition'),
|
|
9
|
-
PositionLevelType = require('./../../../lib/processing/definitions/PositionLevelType'),
|
|
10
|
-
PositionTreeDefinition = require('./../../../lib/processing/definitions/PositionTreeDefinition');
|
|
11
|
-
|
|
12
|
-
describe('When a position container data is gathered', () => {
|
|
13
|
-
'use strict';
|
|
14
|
-
|
|
15
|
-
let positionCounter = 0;
|
|
16
|
-
|
|
17
|
-
function getPosition(portfolio, symbol, currency) {
|
|
18
|
-
return {
|
|
19
|
-
portfolio: portfolio,
|
|
20
|
-
position: (positionCounter++).toString(),
|
|
21
|
-
instrument: {
|
|
22
|
-
symbol: {
|
|
23
|
-
barchart: symbol
|
|
24
|
-
},
|
|
25
|
-
currency: currency || Currency.USD,
|
|
26
|
-
type: InstrumentType.EQUITY
|
|
27
|
-
},
|
|
28
|
-
snapshot: {
|
|
29
|
-
basis: new Decimal(123),
|
|
30
|
-
value: new Decimal(456),
|
|
31
|
-
open: new Decimal(1),
|
|
32
|
-
income: new Decimal(0),
|
|
33
|
-
gain: new Decimal(0),
|
|
34
|
-
buys: new Decimal(50),
|
|
35
|
-
sells: new Decimal(0)
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getSummaries(position, frame, count) {
|
|
41
|
-
const ranges = frame.getRecentRanges(count - 1);
|
|
42
|
-
|
|
43
|
-
return ranges.map((range) => {
|
|
44
|
-
return {
|
|
45
|
-
portfolio: position.portfolio,
|
|
46
|
-
position: position.position,
|
|
47
|
-
frame: frame,
|
|
48
|
-
start: {
|
|
49
|
-
date: range.start,
|
|
50
|
-
open: position.snapshot.open,
|
|
51
|
-
value: position.snapshot.value,
|
|
52
|
-
basis: position.snapshot.basis
|
|
53
|
-
},
|
|
54
|
-
end: {
|
|
55
|
-
date: range.end,
|
|
56
|
-
open: position.snapshot.open,
|
|
57
|
-
value: position.snapshot.value,
|
|
58
|
-
basis: position.snapshot.basis
|
|
59
|
-
},
|
|
60
|
-
period: {
|
|
61
|
-
buys: new Decimal(0),
|
|
62
|
-
sells: new Decimal(0),
|
|
63
|
-
income: new Decimal(0),
|
|
64
|
-
realized: new Decimal(0),
|
|
65
|
-
unrealized: new Decimal(0)
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
describe('for two portfolios, each with the same position, and the second portfolio with an addition position', () => {
|
|
72
|
-
let portfolios;
|
|
73
|
-
let positions;
|
|
74
|
-
let summaries;
|
|
75
|
-
|
|
76
|
-
beforeEach(() => {
|
|
77
|
-
portfolios = [
|
|
78
|
-
{
|
|
79
|
-
portfolio: 'My First Portfolio',
|
|
80
|
-
name: 'a'
|
|
81
|
-
}, {
|
|
82
|
-
portfolio: 'My Second Portfolio',
|
|
83
|
-
name: 'b'
|
|
84
|
-
}
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
positions = [
|
|
88
|
-
getPosition('My First Portfolio', 'AAPL'),
|
|
89
|
-
getPosition('My Second Portfolio', 'AAPL'),
|
|
90
|
-
getPosition('My Second Portfolio', 'TSLA')
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
summaries = positions.reduce((accumulator, position) => {
|
|
94
|
-
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YTD, 1));
|
|
95
|
-
accumulator = accumulator.concat(getSummaries(position, PositionSummaryFrame.YEARLY, 3));
|
|
96
|
-
|
|
97
|
-
return accumulator;
|
|
98
|
-
}, [ ]);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('and a container is created grouping by total, portfolio, and instrument', () => {
|
|
102
|
-
let name;
|
|
103
|
-
let definitions;
|
|
104
|
-
let container;
|
|
105
|
-
|
|
106
|
-
beforeEach(() => {
|
|
107
|
-
definitions = [
|
|
108
|
-
new PositionTreeDefinition(name = 'the only tree', [
|
|
109
|
-
new PositionLevelDefinition('Total', PositionLevelType.OTHER, x => 'totals', x => 'Total', x => Currency.CAD),
|
|
110
|
-
new PositionLevelDefinition('Portfolio', PositionLevelType.PORTFOLIO, x => x.portfolio.portfolio, x => x.portfolio.name, x => Currency.CAD),
|
|
111
|
-
new PositionLevelDefinition('Position', PositionLevelType.POSITION, x => x.position.position, x => x.position.instrument.symbol.barchart, x => x.position.instrument.currency)
|
|
112
|
-
])
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
container = new PositionContainer(definitions, portfolios, positions, summaries);
|
|
117
|
-
} catch (e) {
|
|
118
|
-
console.log(e);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('the "Total" group should have two children groups', () => {
|
|
123
|
-
expect(container.getGroups(name, [ 'totals' ]).length).toEqual(2);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('the "Total" group should have three items', () => {
|
|
127
|
-
expect(container.getGroup(name, [ 'totals' ]).items.length).toEqual(3);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('The "a" portfolio group should have one child group', () => {
|
|
131
|
-
expect(container.getGroups(name, [ 'totals', 'My First Portfolio' ]).length).toEqual(1);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('the "a" portfolio group should have one item', () => {
|
|
135
|
-
expect(container.getGroup(name, [ 'totals', 'My First Portfolio' ]).items.length).toEqual(1);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('The "b" portfolio group should have two child groups', () => {
|
|
139
|
-
expect(container.getGroups(name, [ 'totals', 'My Second Portfolio' ]).length).toEqual(2);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('the "b" portfolio group should have two items', () => {
|
|
143
|
-
expect(container.getGroup(name, [ 'totals', 'My Second Portfolio' ]).items.length).toEqual(2);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
describe('and an item is pulled for one of the positions', function() {
|
|
147
|
-
let item;
|
|
148
|
-
|
|
149
|
-
let todayYear;
|
|
150
|
-
let todayMonth;
|
|
151
|
-
let todayDay;
|
|
152
|
-
|
|
153
|
-
beforeEach(() => {
|
|
154
|
-
item = container.getGroup(name, [ 'totals', 'My First Portfolio' ]).items[0];
|
|
155
|
-
|
|
156
|
-
const today = new Date();
|
|
157
|
-
|
|
158
|
-
todayYear = today.getFullYear();
|
|
159
|
-
todayMonth = today.getMonth() + 1;
|
|
160
|
-
todayDay = today.getDate();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('the current summary should be a YTD summary for this year', () => {
|
|
164
|
-
expect(item.currentSummary).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YTD && s.start.date.format() === `${(todayYear - 1)}-12-31` && s.end.date.format() === `${(todayYear - 0)}-12-31`));
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should have two previous summaries', () => {
|
|
168
|
-
expect(item.previousSummaries.length).toEqual(3);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('the previous (x1) summary should be a YEARLY summary for three years ago', () => {
|
|
172
|
-
expect(item.previousSummaries[0]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 4)}-12-31` && s.end.date.format() === `${(todayYear - 3)}-12-31`));
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('the previous (x2) summary should be a YEARLY summary for the year before last', () => {
|
|
176
|
-
expect(item.previousSummaries[1]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 3)}-12-31` && s.end.date.format() === `${(todayYear - 2)}-12-31`));
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('the previous (x3) summary should be a YEARLY summary for last year', () => {
|
|
180
|
-
expect(item.previousSummaries[2]).toBe(summaries.find(s => s.position === item.position.position && s.frame === PositionSummaryFrame.YEARLY && s.start.date.format() === `${(todayYear - 2)}-12-31` && s.end.date.format() === `${(todayYear - 1)}-12-31`));
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
const PositionSchema = require('./../../../lib/serialization/PositionSchema');
|
|
2
|
-
|
|
3
|
-
describe('When positions are serialized', () => {
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
describe('for a read operation (user error #1)', () => {
|
|
7
|
-
let position;
|
|
8
|
-
let serialized;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
position = {
|
|
12
|
-
"user": "855e15c0-9e32-40ac-9bd9-5f0cc2780111",
|
|
13
|
-
"portfolio": "c2a743e8-8efa-4a88-9a6c-9202d3fec29f",
|
|
14
|
-
"instrument": {
|
|
15
|
-
"id": "TGAM-CASH-USD",
|
|
16
|
-
"name": "US Dollar",
|
|
17
|
-
"type": "CASH",
|
|
18
|
-
"currency": "USD"
|
|
19
|
-
},
|
|
20
|
-
"position": "a5cdc2e8-d9c6-4a1f-8f05-e271a5824f87",
|
|
21
|
-
"transaction": 2987,
|
|
22
|
-
"cash": true,
|
|
23
|
-
"valuation": "AVG",
|
|
24
|
-
"snapshot": {
|
|
25
|
-
"date": "2020-06-11",
|
|
26
|
-
"open": "222105.56",
|
|
27
|
-
"direction": "LONG",
|
|
28
|
-
"buys": "0",
|
|
29
|
-
"sells": "0",
|
|
30
|
-
"gain": "0",
|
|
31
|
-
"basis": "0",
|
|
32
|
-
"income": "0",
|
|
33
|
-
"value": "0"
|
|
34
|
-
},
|
|
35
|
-
"system": {
|
|
36
|
-
"calculate": {
|
|
37
|
-
"processors": 1
|
|
38
|
-
},
|
|
39
|
-
"locked": false
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
serialized = JSON.stringify(position);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe('and the data is deserialized', () => {
|
|
47
|
-
let deserialized;
|
|
48
|
-
|
|
49
|
-
beforeEach(() => {
|
|
50
|
-
const reviver = PositionSchema.CLIENT.schema.getReviver();
|
|
51
|
-
|
|
52
|
-
deserialized = JSON.parse(serialized, reviver);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('the deserialized data should be an object', () => {
|
|
56
|
-
expect(typeof deserialized).toEqual('object');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('the deserialized data should be correct', () => {
|
|
60
|
-
expect(deserialized.position).toEqual(position.position);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
const Day = require('@barchart/common-js/lang/Day'),
|
|
2
|
-
Decimal = require('@barchart/common-js/lang/Decimal');
|
|
3
|
-
|
|
4
|
-
const TransactionType = require('./../../../lib/data/TransactionType');
|
|
5
|
-
|
|
6
|
-
const TransactionSchema = require('./../../../lib/serialization/TransactionSchema');
|
|
7
|
-
|
|
8
|
-
describe('When transactions are serialized', () => {
|
|
9
|
-
'use strict';
|
|
10
|
-
|
|
11
|
-
function transactionsAreEqual(a, b) {
|
|
12
|
-
expect(a.portfolio === b.portfolio).toEqual(true);
|
|
13
|
-
expect(a.position === b.position).toEqual(true);
|
|
14
|
-
expect(a.sequence === b.sequence).toEqual(true);
|
|
15
|
-
expect(a.type === b.type).toEqual(true);
|
|
16
|
-
expect(a.date.getIsEqual(b.date)).toEqual(true);
|
|
17
|
-
expect(a.price.getIsEqual(b.price)).toEqual(true);
|
|
18
|
-
expect(a.quantity.getIsEqual(b.quantity)).toEqual(true);
|
|
19
|
-
expect(a.fee.getIsEqual(b.fee)).toEqual(true);
|
|
20
|
-
expect(a.reinvest === b.reinvest).toEqual(true);
|
|
21
|
-
expect(a.cash === b.cash).toEqual(true);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
describe('for an edit operation (user error #1)', () => {
|
|
25
|
-
let transaction;
|
|
26
|
-
let serialized;
|
|
27
|
-
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
transaction = { };
|
|
30
|
-
|
|
31
|
-
transaction.portfolio = '063e00ea-8d1b-4faa-aedf-f43bdf23590e';
|
|
32
|
-
transaction.position = 'c2eefcde-f8d0-438d-9414-28f307d7b544';
|
|
33
|
-
transaction.sequence = 1;
|
|
34
|
-
transaction.type = TransactionType.BUY;
|
|
35
|
-
transaction.date = new Day(2018, 7, 9);
|
|
36
|
-
transaction.price = new Decimal(15.92);
|
|
37
|
-
transaction.quantity = new Decimal(100);
|
|
38
|
-
transaction.fee = new Decimal(9.95);
|
|
39
|
-
transaction.reinvest = 'default';
|
|
40
|
-
transaction.cash = 'default';
|
|
41
|
-
|
|
42
|
-
const formatted = TransactionSchema.BUY.schema.format(transaction);
|
|
43
|
-
|
|
44
|
-
serialized = JSON.stringify(formatted);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('the serialized data should be correct', () => {
|
|
48
|
-
expect(typeof serialized === 'string').toEqual(true);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('and the data is deserialized', () => {
|
|
52
|
-
let deserialized;
|
|
53
|
-
|
|
54
|
-
beforeEach(() => {
|
|
55
|
-
const reviver = TransactionSchema.BUY.schema.getReviver();
|
|
56
|
-
|
|
57
|
-
deserialized = JSON.parse(serialized, reviver);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('the deserialized data should be correct', () => {
|
|
61
|
-
transactionsAreEqual(transaction, deserialized);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|