mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Many unit tests fail under node 12. It is possible that some of these are caused by issues in node that will be fixed in the future. This also removes the dependency on 'assert-diff' since it is not necessary. It can easily be re-added in the future, if needed.
342 lines
12 KiB
JavaScript
342 lines
12 KiB
JavaScript
/* eslint-disable func-style */
|
|
|
|
const coreTypes = require('../src/coretypes');
|
|
|
|
const _ = require('lodash');
|
|
const assert = require('assert');
|
|
const {encodeAccountID} = require('ripple-address-codec');
|
|
const {binary: {makeParser, readJSON}, Field, Amount, Hash160} = coreTypes;
|
|
const {enums: {TransactionType}} = coreTypes;
|
|
const utils = require('./utils');
|
|
const {parseHexOnly, assertEqualAmountJSON, hexOnly, loadFixture} = utils;
|
|
const {bytesToHex} = require('../src/utils/bytes-utils');
|
|
const fixtures = loadFixture('data-driven-tests.json');
|
|
const {BytesList} = require('../src/serdes/binary-serializer');
|
|
|
|
const __ = hexOnly;
|
|
function unused() {}
|
|
function toJSON(v) {
|
|
return v.toJSON ? v.toJSON() : v;
|
|
}
|
|
|
|
function basicApiTests() {
|
|
const bytes = parseHexOnly('00,01020304,0506', Uint8Array);
|
|
it('can read slices of bytes', () => {
|
|
const parser = makeParser(bytes);
|
|
assert.deepEqual(parser.pos(), 0);
|
|
assert(parser._buf instanceof Uint8Array);
|
|
const read1 = parser.read(1);
|
|
assert(read1 instanceof Uint8Array);
|
|
assert.deepEqual(read1, [0]);
|
|
assert.deepEqual(parser.read(4), [1, 2, 3, 4]);
|
|
assert.deepEqual(parser.read(2), [5, 6]);
|
|
assert.throws(() => parser.read(1));
|
|
});
|
|
it('can read a Uint32 at full', () => {
|
|
const parser = makeParser('FFFFFFFF');
|
|
assert.equal(parser.readUInt32(), 0xFFFFFFFF);
|
|
});
|
|
}
|
|
|
|
function transactionParsingTests() {
|
|
const transaction = {
|
|
json: {
|
|
'Account': 'raD5qJMAShLeHZXf9wjUmo6vRK4arj9cF3',
|
|
'Fee': '10',
|
|
'Flags': 0,
|
|
'Sequence': 103929,
|
|
'SigningPubKey':
|
|
'028472865AF4CB32AA285834B57576B7290AA8C31B459047DB27E16F418D6A7166',
|
|
'TakerGets': {'currency': 'ILS',
|
|
'issuer': 'rNPRNzBB92BVpAhhZr4iXDTveCgV5Pofm9',
|
|
'value': '1694.768'},
|
|
'TakerPays': '98957503520',
|
|
'TransactionType': 'OfferCreate',
|
|
'TxnSignature': __(`
|
|
304502202ABE08D5E78D1E74A4C18F2714F64E87B8BD57444AF
|
|
A5733109EB3C077077520022100DB335EE97386E4C0591CAC02
|
|
4D50E9230D8F171EEB901B5E5E4BD6D1E0AEF98C`)
|
|
},
|
|
binary: __(`
|
|
120007220000000024000195F964400000170A53AC2065D5460561E
|
|
C9DE000000000000000000000000000494C53000000000092D70596
|
|
8936C419CE614BF264B5EEB1CEA47FF468400000000000000A73210
|
|
28472865AF4CB32AA285834B57576B7290AA8C31B459047DB27E16F
|
|
418D6A71667447304502202ABE08D5E78D1E74A4C18F2714F64E87B
|
|
8BD57444AFA5733109EB3C077077520022100DB335EE97386E4C059
|
|
1CAC024D50E9230D8F171EEB901B5E5E4BD6D1E0AEF98C811439408
|
|
A69F0895E62149CFCC006FB89FA7D1E6E5D`)
|
|
};
|
|
|
|
const tx_json = transaction.json;
|
|
// These tests are basically development logs
|
|
|
|
it('can be done with low level apis', () => {
|
|
const parser = makeParser(transaction.binary);
|
|
|
|
assert.equal(parser.readField(), Field.TransactionType);
|
|
assert.equal(parser.readUInt16(), 7);
|
|
assert.equal(parser.readField(), Field.Flags);
|
|
assert.equal(parser.readUInt32(), 0);
|
|
assert.equal(parser.readField(), Field.Sequence);
|
|
assert.equal(parser.readUInt32(), 103929);
|
|
assert.equal(parser.readField(), Field.TakerPays);
|
|
parser.read(8);
|
|
assert.equal(parser.readField(), Field.TakerGets);
|
|
// amount value
|
|
assert(parser.read(8));
|
|
// amount currency
|
|
assert(Hash160.fromParser(parser));
|
|
assert.equal(encodeAccountID(parser.read(20)),
|
|
tx_json.TakerGets.issuer);
|
|
assert.equal(parser.readField(), Field.Fee);
|
|
assert(parser.read(8));
|
|
assert.equal(parser.readField(), Field.SigningPubKey);
|
|
assert.equal(parser.readVLLength(), 33);
|
|
assert.equal(bytesToHex(parser.read(33)), tx_json.SigningPubKey);
|
|
assert.equal(parser.readField(), Field.TxnSignature);
|
|
assert.equal(bytesToHex(parser.readVL()), tx_json.TxnSignature);
|
|
assert.equal(parser.readField(), Field.Account);
|
|
assert.equal(encodeAccountID(parser.readVL()), tx_json.Account);
|
|
assert(parser.end());
|
|
});
|
|
|
|
it('can be done with high level apis', () => {
|
|
const parser = makeParser(transaction.binary);
|
|
function readField() {
|
|
return parser.readFieldAndValue();
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.TransactionType);
|
|
assert.equal(value, TransactionType.OfferCreate);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.Flags);
|
|
assert.equal(value, 0);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.Sequence);
|
|
assert.equal(value, 103929);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.TakerPays);
|
|
assert.equal(value.currency.isNative(), true);
|
|
assert.equal(value.currency.toJSON(), 'XRP');
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.TakerGets);
|
|
assert.equal(value.currency.isNative(), false);
|
|
assert.equal(value.issuer.toJSON(), tx_json.TakerGets.issuer);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.Fee);
|
|
assert.equal(value.currency.isNative(), true);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.SigningPubKey);
|
|
assert.equal(value.toJSON(), tx_json.SigningPubKey);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.TxnSignature);
|
|
assert.equal(value.toJSON(), tx_json.TxnSignature);
|
|
}
|
|
{
|
|
const [field, value] = readField();
|
|
assert.equal(field, Field.Account);
|
|
assert.equal(value.toJSON(), tx_json.Account);
|
|
}
|
|
assert(parser.end());
|
|
});
|
|
|
|
it('can be done with higher level apis', () => {
|
|
const parser = makeParser(transaction.binary);
|
|
const jsonFromBinary = readJSON(parser);
|
|
assert.deepEqual(jsonFromBinary, tx_json);
|
|
});
|
|
|
|
it('readJSON (binary.decode) does not return STObject ', () => {
|
|
const parser = makeParser(transaction.binary);
|
|
const jsonFromBinary = readJSON(parser);
|
|
assert((jsonFromBinary instanceof coreTypes.STObject) === false);
|
|
assert(_.isPlainObject(jsonFromBinary));
|
|
});
|
|
}
|
|
|
|
function amountParsingTests() {
|
|
_.filter(fixtures.values_tests, {type: 'Amount'}).forEach((f, i) => {
|
|
if (f.error) {
|
|
return;
|
|
}
|
|
const parser = makeParser(f.expected_hex);
|
|
const testName =
|
|
`values_tests[${i}] parses ${f.expected_hex.slice(0, 16)}...
|
|
as ${JSON.stringify(f.test_json)}`;
|
|
it(testName, () => {
|
|
const value = parser.readType(Amount);
|
|
// May not actually be in canonical form. The fixtures are to be used
|
|
// also for json -> binary;
|
|
assertEqualAmountJSON(toJSON(value), f.test_json);
|
|
if (f.exponent) {
|
|
assert.equal(value.exponent(), f.exponent);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function fieldParsingTests() {
|
|
fixtures.fields_tests.forEach((f, i) => {
|
|
const parser = makeParser(f.expected_hex);
|
|
it(`fields[${i}]: parses ${f.expected_hex} as ${f.name}`, () => {
|
|
const field = parser.readField();
|
|
assert.equal(field.name, f.name);
|
|
assert.equal(field.type.name, f.type_name);
|
|
});
|
|
});
|
|
}
|
|
|
|
function assertRecyclable(json, forField) {
|
|
const Type = forField.associatedType;
|
|
const recycled = Type.from(json).toJSON();
|
|
assert.deepEqual(recycled, json);
|
|
const sink = new BytesList();
|
|
Type.from(recycled).toBytesSink(sink);
|
|
const recycledAgain = makeParser(sink.toHex())
|
|
.readType(Type)
|
|
.toJSON();
|
|
assert.deepEqual(recycledAgain, json);
|
|
}
|
|
|
|
function nestedObjectTests() {
|
|
function disabled(i) {
|
|
unused(i);
|
|
return false; // !_.includes([2], i);
|
|
}
|
|
|
|
fixtures.whole_objects.forEach((f, i) => {
|
|
if (disabled(i)) {
|
|
return;
|
|
}
|
|
|
|
it(`whole_objects[${i}]: can parse blob into
|
|
${JSON.stringify(f.tx_json)}`,
|
|
/* */ () => {
|
|
|
|
const parser = makeParser(f.blob_with_no_signing);
|
|
let ix = 0;
|
|
while (!parser.end()) {
|
|
const [field, value] = parser.readFieldAndValue();
|
|
const expected = f.fields[ix];
|
|
const expectedJSON = expected[1].json;
|
|
const expectedField = expected[0];
|
|
const actual = toJSON(value);
|
|
|
|
try {
|
|
assert.deepEqual(actual, expectedJSON);
|
|
} catch (e) {
|
|
throw new Error(`${e} ${field} a: ${actual} e: ${expectedJSON}`);
|
|
}
|
|
assert.equal(field.name, expectedField);
|
|
assertRecyclable(actual, field);
|
|
ix++;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function pathSetBinaryTests() {
|
|
const bytes = __(
|
|
`1200002200000000240000002E2E00004BF161D4C71AFD498D00000000000000
|
|
0000000000000055534400000000000A20B3C85F482532A9578DBB3950B85CA0
|
|
6594D168400000000000000A69D446F8038585E9400000000000000000000000
|
|
00425443000000000078CA21A6014541AB7B26C3929B9E0CD8C284D61C732103
|
|
A4665B1F0B7AE2BCA12E2DB80A192125BBEA660F80E9CEE137BA444C1B0769EC
|
|
7447304502205A964536805E35785C659D1F9670D057749AE39668175D6AA75D
|
|
25B218FE682E0221009252C0E5DDD5F2712A48F211669DE17B54113918E0D2C2
|
|
66F818095E9339D7D3811478CA21A6014541AB7B26C3929B9E0CD8C284D61C83
|
|
140A20B3C85F482532A9578DBB3950B85CA06594D1011231585E1F3BD02A15D6
|
|
185F8BB9B57CC60DEDDB37C10000000000000000000000004254430000000000
|
|
585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D694C
|
|
8531CDEECBE84F33670000000000000000000000004254430000000000E4FE68
|
|
7C90257D3D2D694C8531CDEECBE84F3367310A20B3C85F482532A9578DBB3950
|
|
B85CA06594D100000000000000000000000042544300000000000A20B3C85F48
|
|
2532A9578DBB3950B85CA06594D1300000000000000000000000005553440000
|
|
0000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A15
|
|
D6185F8BB9B57CC60DEDDB37C100000000000000000000000042544300000000
|
|
00585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C131E4FE687C90257D3D2D69
|
|
4C8531CDEECBE84F33670000000000000000000000004254430000000000E4FE
|
|
687C90257D3D2D694C8531CDEECBE84F33673115036E2D3F5437A83E5AC3CAEE
|
|
34FF2C21DEB618000000000000000000000000425443000000000015036E2D3F
|
|
5437A83E5AC3CAEE34FF2C21DEB6183000000000000000000000000055534400
|
|
000000000A20B3C85F482532A9578DBB3950B85CA06594D1FF31585E1F3BD02A
|
|
15D6185F8BB9B57CC60DEDDB37C1000000000000000000000000425443000000
|
|
0000585E1F3BD02A15D6185F8BB9B57CC60DEDDB37C13157180C769B66D942EE
|
|
69E6DCC940CA48D82337AD000000000000000000000000425443000000000057
|
|
180C769B66D942EE69E6DCC940CA48D82337AD10000000000000000000000000
|
|
58525000000000003000000000000000000000000055534400000000000A20B3
|
|
C85F482532A9578DBB3950B85CA06594D100`);
|
|
|
|
const expectedJSON =
|
|
[[{account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
|
|
currency: 'BTC',
|
|
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K'},
|
|
{account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo',
|
|
currency: 'BTC',
|
|
issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo'},
|
|
{account: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
|
|
currency: 'BTC',
|
|
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'},
|
|
{currency: 'USD',
|
|
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'}],
|
|
[{account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
|
|
currency: 'BTC',
|
|
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K'},
|
|
{account: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo',
|
|
currency: 'BTC',
|
|
issuer: 'rM1oqKtfh1zgjdAgbFmaRm3btfGBX25xVo'},
|
|
{account: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi',
|
|
currency: 'BTC',
|
|
issuer: 'rpvfJ4mR6QQAeogpXEKnuyGBx8mYCSnYZi'},
|
|
{currency: 'USD',
|
|
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'}],
|
|
[{account: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
|
|
currency: 'BTC',
|
|
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K'},
|
|
{account: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn',
|
|
currency: 'BTC',
|
|
issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn'},
|
|
{currency: '0000000000000000000000005852500000000000'},
|
|
{currency: 'USD',
|
|
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B'}]];
|
|
|
|
it('works with long paths', () => {
|
|
const parser = makeParser(bytes);
|
|
const txn = readJSON(parser);
|
|
assert.deepEqual(txn.Paths, expectedJSON);
|
|
// TODO: this should go elsewhere
|
|
assert.deepEqual(
|
|
coreTypes.PathSet.from(txn.Paths).toJSON(),
|
|
expectedJSON
|
|
);
|
|
});
|
|
}
|
|
|
|
describe('BinaryParser', function() {
|
|
function dataDrivenTests() {
|
|
describe('Amount parsing tests', amountParsingTests);
|
|
describe('Field Tests', fieldParsingTests);
|
|
describe('Parsing nested objects', nestedObjectTests);
|
|
}
|
|
describe('pathSetBinaryTests', pathSetBinaryTests);
|
|
describe('Basic API', basicApiTests);
|
|
describe('Parsing a transaction', transactionParsingTests);
|
|
describe('Data Driven Tests', dataDrivenTests);
|
|
});
|