@barchart/portfolio-api-common 1.3.21 → 1.3.25
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/.jshintrc +2 -1
- package/README.md +29 -4
- package/buildspec.yml +15 -0
- package/gulpfile.js +20 -30
- package/lib/api/failures/PortfolioFailureType.js +2 -2
- package/lib/data/TransactionValidator.js +5 -5
- package/lib/serialization/TransactionSchema.js +4 -2
- package/package.json +2 -3
- package/test/SpecRunner.js +19 -15
- package/test/specs/data/TransactionValidatorSpec.js +4 -4
package/.jshintrc
CHANGED
package/README.md
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
# @barchart/portfolio-api-common
|
|
2
|
-
## Barchart Portfolio API Common Components
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
[](https://github.com/barchart/portfolio-api-common)
|
|
5
4
|
|
|
6
|
-
*
|
|
7
|
-
|
|
5
|
+
A *private* library of shared JavaScript code pertaining to the paper-trading portfolio system.
|
|
6
|
+
|
|
7
|
+
### Overview
|
|
8
|
+
|
|
9
|
+
Simply put, this project contains code that runs on both the servers (i.e. Serverless applications) and clients (e.g. browser, mobile, etc).
|
|
10
|
+
|
|
11
|
+
#### [lib/serialization](https://github.com/barchart/portfolio-api-common/tree/master/lib/serialization)
|
|
12
|
+
|
|
13
|
+
Data is passed between client and server in JSON format. However, the code works with more complex types. For example, [Decimal](https://github.com/barchart/barchart-common-js/blob/master/lang/Decimal.js) instances are used in place of [native JavaScript floats](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number). [Day](https://github.com/barchart/barchart-common-js/blob/master/lang/Day.js) instances are used instead of [native JavaScript Dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date).
|
|
14
|
+
|
|
15
|
+
So, before data is exchanged, it must be converted to pure JSON. Conversely, when data is received, as pure JSON, its translated into more complex types before use. This is facilitated by the [Schema](https://github.com/barchart/barchart-common-js/blob/master/serialization/json/Schema.js) definitions which build custom "reviver" functions for [JSON parsing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
|
|
16
|
+
|
|
17
|
+
#### [lib/processing](https://github.com/barchart/portfolio-api-common/tree/master/lib/processing)
|
|
18
|
+
|
|
19
|
+
For reporting and display purposes, positions can be grouped together (by asset class, by portfolio, by user, etc). This code supports aggregation and gain/loss calculation. It is used by server-generated reports and dynamic user interfaces.
|
|
20
|
+
|
|
21
|
+
### Notable Consumers
|
|
22
|
+
|
|
23
|
+
* [aws-lambda-portfolio](https://github.com/barchart/aws-lambda-portfolio) - Serverless applications (i.e. the servers)
|
|
24
|
+
* [portfolio-client-js](https://github.com/barchart/portfolio-client-js) - JavaScript client SDK for communicating with server API's.
|
|
25
|
+
* [tgam-portfolio-ui-js](https://github.com/barchart/tgam-portfolio-ui-js) - A dynamic, single-page HTML UI.
|
|
26
|
+
|
|
27
|
+
### Package Managers
|
|
28
|
+
|
|
29
|
+
This library has been published as a *private* module to NPM as [@barchart/portfolio-api-common](https://www.npmjs.com/package/@barchart/portfolio-api-common).
|
|
30
|
+
|
|
31
|
+
> npm login
|
|
32
|
+
> npm install @barchart/portfolio-api-common -S
|
package/buildspec.yml
ADDED
package/gulpfile.js
CHANGED
|
@@ -5,7 +5,6 @@ const fs = require('fs');
|
|
|
5
5
|
const browserify = require('browserify'),
|
|
6
6
|
buffer = require('vinyl-buffer'),
|
|
7
7
|
bump = require('gulp-bump'),
|
|
8
|
-
exec = require('child_process').exec,
|
|
9
8
|
git = require('gulp-git'),
|
|
10
9
|
gitStatus = require('git-get-status'),
|
|
11
10
|
glob = require('glob'),
|
|
@@ -14,7 +13,7 @@ const browserify = require('browserify'),
|
|
|
14
13
|
source = require('vinyl-source-stream');
|
|
15
14
|
|
|
16
15
|
function getVersionFromPackage() {
|
|
17
|
-
|
|
16
|
+
return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
gulp.task('ensure-clean-working-directory', (cb) => {
|
|
@@ -33,35 +32,26 @@ gulp.task('bump-version', () => {
|
|
|
33
32
|
.pipe(gulp.dest('./'));
|
|
34
33
|
});
|
|
35
34
|
|
|
36
|
-
gulp.task('document', (cb) => {
|
|
37
|
-
exec('jsdoc . -c jsdoc.json -r -d docs', (error, stdout, stderr) => {
|
|
38
|
-
console.log(stdout);
|
|
39
|
-
console.log(stderr);
|
|
40
|
-
|
|
41
|
-
cb();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
35
|
gulp.task('commit-changes', () => {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
36
|
+
return gulp.src([ './', './test/', './package.json' ])
|
|
37
|
+
.pipe(git.add())
|
|
38
|
+
.pipe(git.commit('Release. Bump version number'));
|
|
49
39
|
});
|
|
50
40
|
|
|
51
41
|
gulp.task('push-changes', (cb) => {
|
|
52
|
-
|
|
42
|
+
git.push('origin', 'master', cb);
|
|
53
43
|
});
|
|
54
44
|
|
|
55
45
|
gulp.task('create-tag', (cb) => {
|
|
56
|
-
|
|
46
|
+
const version = getVersionFromPackage();
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
git.tag(version, 'Release ' + version, (error) => {
|
|
49
|
+
if (error) {
|
|
50
|
+
return cb(error);
|
|
51
|
+
}
|
|
62
52
|
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
git.push('origin', 'master', { args: '--tags' }, cb);
|
|
54
|
+
});
|
|
65
55
|
});
|
|
66
56
|
|
|
67
57
|
gulp.task('build-test-bundle', () => {
|
|
@@ -73,13 +63,13 @@ gulp.task('build-test-bundle', () => {
|
|
|
73
63
|
});
|
|
74
64
|
|
|
75
65
|
gulp.task('execute-browser-tests', () => {
|
|
76
|
-
|
|
77
|
-
|
|
66
|
+
return gulp.src('test/SpecRunner.js')
|
|
67
|
+
.pipe(jasmine());
|
|
78
68
|
});
|
|
79
69
|
|
|
80
70
|
gulp.task('execute-node-tests', () => {
|
|
81
|
-
|
|
82
|
-
|
|
71
|
+
return gulp.src(['test/specs/**/*.js'])
|
|
72
|
+
.pipe(jasmine());
|
|
83
73
|
});
|
|
84
74
|
|
|
85
75
|
gulp.task('execute-tests', gulp.series(
|
|
@@ -91,7 +81,6 @@ gulp.task('execute-tests', gulp.series(
|
|
|
91
81
|
gulp.task('release', gulp.series(
|
|
92
82
|
'ensure-clean-working-directory',
|
|
93
83
|
'execute-tests',
|
|
94
|
-
'document',
|
|
95
84
|
'bump-version',
|
|
96
85
|
'commit-changes',
|
|
97
86
|
'push-changes',
|
|
@@ -99,9 +88,10 @@ gulp.task('release', gulp.series(
|
|
|
99
88
|
));
|
|
100
89
|
|
|
101
90
|
gulp.task('lint', () => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
91
|
+
return gulp.src([ './**/*.js', './test/specs/**/*.js', '!./node_modules/**', '!./docs/**', '!./test/SpecRunner.js' ])
|
|
92
|
+
.pipe(jshint({'esversion': 6}))
|
|
93
|
+
.pipe(jshint.reporter('default'))
|
|
94
|
+
.pipe(jshint.reporter('fail'));
|
|
105
95
|
});
|
|
106
96
|
|
|
107
97
|
gulp.task('test', gulp.series('execute-tests'));
|
|
@@ -356,13 +356,13 @@ module.exports = (() => {
|
|
|
356
356
|
const transactionCreateFailedInstrumentCorrupt = new FailureType('TRANSACTION_CREATE_FAILED_INSTRUMENT_CORRUPT', 'Unable to create transaction, corporate action history for {U|symbol} cannot be located.');
|
|
357
357
|
|
|
358
358
|
const transactionDeleteFailedOutOfSequence = new FailureType('TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE', 'Deleting any transaction, except for the most recent, will cause transaction history to be re-written. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
|
|
359
|
-
const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.');
|
|
359
|
+
const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.', false);
|
|
360
360
|
const transactionDeleteFailedDirectionSwitchOnRewrite = new FailureType('TRANSACTION_DELETE_FAILED_DIRECTION_SWITCH_ON_REWRITE', 'Deleting this transaction would cause your history to be re-written and the position to switch from long to short (i.e. positive to negative) or vice versa.', false);
|
|
361
361
|
const transactionDeleteFailedPositionLocked = new FailureType('TRANSACTION_DELETE_FAILED_POSITION_LOCKED', 'Unable to delete transaction, your {L|description} history is being recalculated. Please wait a minute or two and retry.');
|
|
362
362
|
const transactionDeleteFailedTypeReserved = new FailureType('TRANSACTION_DELETE_FAILED_TYPE_RESERVED', 'Unable to delete {U|type.description} transaction, this type of transaction is managed by the system.');
|
|
363
363
|
|
|
364
364
|
const transactionEditFailedInvalidDate = new FailureType('TRANSACTION_EDIT_FAILED_INVALID_DATE', 'Unable to edit transaction with given date.');
|
|
365
|
-
const transactionEditFailedNoTransaction = new FailureType('TRANSACTION_EDIT_FAILED_NO_TRANSACTION', 'Unable to edit transaction. The referenced transaction does not exist.');
|
|
365
|
+
const transactionEditFailedNoTransaction = new FailureType('TRANSACTION_EDIT_FAILED_NO_TRANSACTION', 'Unable to edit transaction. The referenced transaction does not exist.', false);
|
|
366
366
|
const transactionEditFailedTypeReserved = new FailureType('TRANSACTION_EDIT_FAILED_TYPE_RESERVED', 'Unable to edit {U|type.description} transaction, this type of transaction is managed by the system.');
|
|
367
367
|
|
|
368
368
|
return PortfolioFailureType;
|
|
@@ -70,20 +70,20 @@ module.exports = (() => {
|
|
|
70
70
|
return transactions.every((t) => {
|
|
71
71
|
let valid = true;
|
|
72
72
|
|
|
73
|
-
if (is.object(t.reference) && is.string(t.reference.root) && is.
|
|
73
|
+
if (is.object(t.reference) && is.string(t.reference.root) && is.string(t.reference.transaction)) {
|
|
74
74
|
const root = t.reference.root;
|
|
75
|
-
const
|
|
75
|
+
const transaction = t.reference.transaction;
|
|
76
76
|
|
|
77
77
|
if (!references.hasOwnProperty(root)) {
|
|
78
78
|
references[root] = [ ];
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const
|
|
81
|
+
const transactions = references[root];
|
|
82
82
|
|
|
83
|
-
if (
|
|
83
|
+
if (transactions.some(t => t === transaction)) {
|
|
84
84
|
valid = false;
|
|
85
85
|
} else {
|
|
86
|
-
|
|
86
|
+
transactions.push(transaction);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -130,6 +130,7 @@ module.exports = (() => {
|
|
|
130
130
|
const complete = new TransactionSchema(SchemaBuilder.withName('complete')
|
|
131
131
|
.withField('portfolio', DataType.STRING)
|
|
132
132
|
.withField('position', DataType.STRING)
|
|
133
|
+
.withField('transaction', DataType.STRING)
|
|
133
134
|
.withField('sequence', DataType.NUMBER)
|
|
134
135
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
135
136
|
.withField('date', DataType.DAY)
|
|
@@ -138,7 +139,7 @@ module.exports = (() => {
|
|
|
138
139
|
.withField('quantity', DataType.DECIMAL)
|
|
139
140
|
.withField('fee', DataType.DECIMAL, true)
|
|
140
141
|
.withField('reference.position', DataType.STRING, true)
|
|
141
|
-
.withField('reference.
|
|
142
|
+
.withField('reference.transaction', DataType.STRING, true)
|
|
142
143
|
.withField('snapshot.open', DataType.DECIMAL)
|
|
143
144
|
.withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
|
|
144
145
|
.withField('snapshot.buys', DataType.DECIMAL)
|
|
@@ -179,6 +180,7 @@ module.exports = (() => {
|
|
|
179
180
|
const client = new TransactionSchema(SchemaBuilder.withName('client')
|
|
180
181
|
.withField('portfolio', DataType.STRING)
|
|
181
182
|
.withField('position', DataType.STRING)
|
|
183
|
+
.withField('transaction', DataType.STRING)
|
|
182
184
|
.withField('sequence', DataType.NUMBER)
|
|
183
185
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
184
186
|
.withField('date', DataType.DAY)
|
|
@@ -187,7 +189,7 @@ module.exports = (() => {
|
|
|
187
189
|
.withField('quantity', DataType.DECIMAL)
|
|
188
190
|
.withField('fee', DataType.DECIMAL, true)
|
|
189
191
|
.withField('reference.position', DataType.STRING, true)
|
|
190
|
-
.withField('reference.
|
|
192
|
+
.withField('reference.transaction', DataType.NUMBER, true)
|
|
191
193
|
.withField('snapshot.open', DataType.DECIMAL)
|
|
192
194
|
.withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
|
|
193
195
|
.withField('snapshot.buys', DataType.DECIMAL)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barchart/portfolio-api-common",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "Common
|
|
3
|
+
"version": "1.3.25",
|
|
4
|
+
"description": "Common code used by the Portfolio system",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bryan Ingle",
|
|
7
7
|
"email": "bryan.ingle@barchart.com",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"gulp-bump": "~1.0.0",
|
|
23
23
|
"gulp-git": "^2.9.0",
|
|
24
24
|
"gulp-jasmine": "^2.2.1",
|
|
25
|
-
"gulp-jsdoc3": "^1.0.1",
|
|
26
25
|
"gulp-jshint": "~2.1.0",
|
|
27
26
|
"jsdoc": "^3.5.5",
|
|
28
27
|
"jshint": "2.9.5",
|
package/test/SpecRunner.js
CHANGED
|
@@ -1357,20 +1357,20 @@ module.exports = (() => {
|
|
|
1357
1357
|
return transactions.every((t) => {
|
|
1358
1358
|
let valid = true;
|
|
1359
1359
|
|
|
1360
|
-
if (is.object(t.reference) && is.string(t.reference.root) && is.
|
|
1360
|
+
if (is.object(t.reference) && is.string(t.reference.root) && is.string(t.reference.transaction)) {
|
|
1361
1361
|
const root = t.reference.root;
|
|
1362
|
-
const
|
|
1362
|
+
const transaction = t.reference.transaction;
|
|
1363
1363
|
|
|
1364
1364
|
if (!references.hasOwnProperty(root)) {
|
|
1365
1365
|
references[root] = [ ];
|
|
1366
1366
|
}
|
|
1367
1367
|
|
|
1368
|
-
const
|
|
1368
|
+
const transactions = references[root];
|
|
1369
1369
|
|
|
1370
|
-
if (
|
|
1370
|
+
if (transactions.some(t => t === transaction)) {
|
|
1371
1371
|
valid = false;
|
|
1372
1372
|
} else {
|
|
1373
|
-
|
|
1373
|
+
transactions.push(transaction);
|
|
1374
1374
|
}
|
|
1375
1375
|
}
|
|
1376
1376
|
|
|
@@ -4980,6 +4980,7 @@ module.exports = (() => {
|
|
|
4980
4980
|
const complete = new TransactionSchema(SchemaBuilder.withName('complete')
|
|
4981
4981
|
.withField('portfolio', DataType.STRING)
|
|
4982
4982
|
.withField('position', DataType.STRING)
|
|
4983
|
+
.withField('transaction', DataType.STRING)
|
|
4983
4984
|
.withField('sequence', DataType.NUMBER)
|
|
4984
4985
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
4985
4986
|
.withField('date', DataType.DAY)
|
|
@@ -4988,7 +4989,7 @@ module.exports = (() => {
|
|
|
4988
4989
|
.withField('quantity', DataType.DECIMAL)
|
|
4989
4990
|
.withField('fee', DataType.DECIMAL, true)
|
|
4990
4991
|
.withField('reference.position', DataType.STRING, true)
|
|
4991
|
-
.withField('reference.
|
|
4992
|
+
.withField('reference.transaction', DataType.STRING, true)
|
|
4992
4993
|
.withField('snapshot.open', DataType.DECIMAL)
|
|
4993
4994
|
.withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
|
|
4994
4995
|
.withField('snapshot.buys', DataType.DECIMAL)
|
|
@@ -5029,6 +5030,7 @@ module.exports = (() => {
|
|
|
5029
5030
|
const client = new TransactionSchema(SchemaBuilder.withName('client')
|
|
5030
5031
|
.withField('portfolio', DataType.STRING)
|
|
5031
5032
|
.withField('position', DataType.STRING)
|
|
5033
|
+
.withField('transaction', DataType.STRING)
|
|
5032
5034
|
.withField('sequence', DataType.NUMBER)
|
|
5033
5035
|
.withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
|
|
5034
5036
|
.withField('date', DataType.DAY)
|
|
@@ -5037,7 +5039,7 @@ module.exports = (() => {
|
|
|
5037
5039
|
.withField('quantity', DataType.DECIMAL)
|
|
5038
5040
|
.withField('fee', DataType.DECIMAL, true)
|
|
5039
5041
|
.withField('reference.position', DataType.STRING, true)
|
|
5040
|
-
.withField('reference.
|
|
5042
|
+
.withField('reference.transaction', DataType.NUMBER, true)
|
|
5041
5043
|
.withField('snapshot.open', DataType.DECIMAL)
|
|
5042
5044
|
.withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
|
|
5043
5045
|
.withField('snapshot.buys', DataType.DECIMAL)
|
|
@@ -7488,6 +7490,7 @@ module.exports = (() => {
|
|
|
7488
7490
|
* item's value. If no matching item can be found, a null value is returned.
|
|
7489
7491
|
*
|
|
7490
7492
|
* @public
|
|
7493
|
+
* @static
|
|
7491
7494
|
* @param {Function} type - The enumeration type.
|
|
7492
7495
|
* @param {String} code - The enumeration item's code.
|
|
7493
7496
|
* @returns {*|null}
|
|
@@ -7501,6 +7504,7 @@ module.exports = (() => {
|
|
|
7501
7504
|
* Returns all of the enumeration's items (given an enumeration type).
|
|
7502
7505
|
*
|
|
7503
7506
|
* @public
|
|
7507
|
+
* @static
|
|
7504
7508
|
* @param {Function} type - The enumeration to list.
|
|
7505
7509
|
* @returns {Array}
|
|
7506
7510
|
*/
|
|
@@ -9029,11 +9033,11 @@ module.exports = (() => {
|
|
|
9029
9033
|
simple(fn) {
|
|
9030
9034
|
const cache = {};
|
|
9031
9035
|
return x => {
|
|
9032
|
-
if (cache.hasOwnProperty(x)) {
|
|
9033
|
-
|
|
9034
|
-
} else {
|
|
9035
|
-
return cache[x] = fn(x);
|
|
9036
|
+
if (!cache.hasOwnProperty(x)) {
|
|
9037
|
+
cache[x] = fn(x);
|
|
9036
9038
|
}
|
|
9039
|
+
|
|
9040
|
+
return cache[x];
|
|
9037
9041
|
};
|
|
9038
9042
|
},
|
|
9039
9043
|
|
|
@@ -17842,8 +17846,8 @@ describe('When validating transaction order', () => {
|
|
|
17842
17846
|
describe('When validating transaction references', () => {
|
|
17843
17847
|
'use strict';
|
|
17844
17848
|
|
|
17845
|
-
const build = (root,
|
|
17846
|
-
return { reference: { root: root,
|
|
17849
|
+
const build = (root, transaction) => {
|
|
17850
|
+
return { reference: { root: root, transaction: transaction } };
|
|
17847
17851
|
};
|
|
17848
17852
|
|
|
17849
17853
|
it('An array of zero transactions should be valid', () => {
|
|
@@ -17855,11 +17859,11 @@ describe('When validating transaction references', () => {
|
|
|
17855
17859
|
});
|
|
17856
17860
|
|
|
17857
17861
|
it('An array with distinct references should be valid', () => {
|
|
17858
|
-
expect(TransactionValidator.validateReferences([ build('a',
|
|
17862
|
+
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'y') ])).toEqual(true);
|
|
17859
17863
|
});
|
|
17860
17864
|
|
|
17861
17865
|
it('An array with non-distinct references should be not valid', () => {
|
|
17862
|
-
expect(TransactionValidator.validateReferences([ build('a',
|
|
17866
|
+
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'x'), build('a', 'y') ])).toEqual(false);
|
|
17863
17867
|
});
|
|
17864
17868
|
});
|
|
17865
17869
|
|
|
@@ -58,8 +58,8 @@ describe('When validating transaction order', () => {
|
|
|
58
58
|
describe('When validating transaction references', () => {
|
|
59
59
|
'use strict';
|
|
60
60
|
|
|
61
|
-
const build = (root,
|
|
62
|
-
return { reference: { root: root,
|
|
61
|
+
const build = (root, transaction) => {
|
|
62
|
+
return { reference: { root: root, transaction: transaction } };
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
it('An array of zero transactions should be valid', () => {
|
|
@@ -71,11 +71,11 @@ describe('When validating transaction references', () => {
|
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it('An array with distinct references should be valid', () => {
|
|
74
|
-
expect(TransactionValidator.validateReferences([ build('a',
|
|
74
|
+
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'y') ])).toEqual(true);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
it('An array with non-distinct references should be not valid', () => {
|
|
78
|
-
expect(TransactionValidator.validateReferences([ build('a',
|
|
78
|
+
expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'x'), build('a', 'y') ])).toEqual(false);
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
|