mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-15 10:05:48 +00:00
Initial change from Babel/JS to TypeScript (#70)
* will compile as typescript * migrated test suite to use JestJS * Migrated to Jest testing framework and typescript source files * updated deps * updated prepublish * resolved 1 failing test * changed decimal .0 on four tests, it appears that these were the only four tests expecting integer values to have '.0' * added linter * added package-lock * removed tslint in favor of eslint * changed yarn to npm * updated version 2.6->3.0 * removing package lock * updated node version in nvmrc and jest version in package * removed nvmrc * removed some unused functions * replaced data driven with file from master * commitint yarn.lock * removing babel as a dependency in favor of typescript compiling to es5 * removing babel deps * resolved testing issues by migrating helper function * added partial linting functionality for test suite * updated imports for decodeLedgerData * updated test * updated yarn.lock * removed a console.log * added eslint-jest-plugin to package * reverting to old linting, will add linting in next PR * removed comments in shamap * re-adding .nvmrc * npm -> yarn * added . to .eslintrc * added .eslintrc * removing linting for this PR * Changed linting to print a message so that linting doesnt fail in CI * changing back * added newline so diff wont show * removed eslint deps, since linting will be dealt with in a later PR * changed function calls to describe(...)
This commit is contained in:
@@ -1,43 +0,0 @@
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const utils = require('./utils');
|
||||
const {Amount} = require('../src/coretypes');
|
||||
const {loadFixture} = utils;
|
||||
const fixtures = loadFixture('data-driven-tests.json');
|
||||
|
||||
function amountErrorTests() {
|
||||
_.filter(fixtures.values_tests, {type: 'Amount'}).forEach(f => {
|
||||
// We only want these with errors
|
||||
if (!f.error) {
|
||||
return
|
||||
}
|
||||
const testName = `${JSON.stringify(f.test_json)}\n\tis invalid ` +
|
||||
`because: ${f.error}`
|
||||
it(testName, () => {
|
||||
assert.throws(() => {
|
||||
Amount.from(f.test_json);
|
||||
}, JSON.stringify(f.test_json));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe('Amount', function() {
|
||||
it('can be parsed from', function() {
|
||||
assert(Amount.from('1000000') instanceof Amount);
|
||||
assert.equal(Amount.from('1000000').valueString(), '1000000');
|
||||
const fixture = {
|
||||
'value': '1',
|
||||
'issuer': '0000000000000000000000000000000000000000',
|
||||
'currency': 'USD'
|
||||
};
|
||||
const amt = Amount.from(fixture);
|
||||
const rewritten = {
|
||||
'value': '1',
|
||||
'issuer': 'rrrrrrrrrrrrrrrrrrrrrhoLvTp',
|
||||
'currency': 'USD'
|
||||
};
|
||||
assert.deepEqual(amt.toJSON(), rewritten);
|
||||
});
|
||||
amountErrorTests()
|
||||
});
|
||||
|
||||
42
packages/ripple-binary-codec/test/amount.test.js
Normal file
42
packages/ripple-binary-codec/test/amount.test.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const _ = require('lodash')
|
||||
const { loadFixture } = require('./utils')
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { Amount } = coreTypes
|
||||
const fixtures = loadFixture('data-driven-tests.json')
|
||||
|
||||
function amountErrorTests () {
|
||||
_.filter(fixtures.values_tests, { type: 'Amount' }).forEach(f => {
|
||||
// We only want these with errors
|
||||
if (!f.error) {
|
||||
return
|
||||
}
|
||||
const testName = `${JSON.stringify(f.test_json)}\n\tis invalid ` +
|
||||
`because: ${f.error}`
|
||||
it(testName, () => {
|
||||
expect(() => {
|
||||
Amount.from(f.test_json)
|
||||
JSON.stringify(f.test_json)
|
||||
}).toThrow()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
describe('Amount', function () {
|
||||
it('can be parsed from', function () {
|
||||
expect(Amount.from('1000000') instanceof Amount).toBe(true)
|
||||
expect(Amount.from('1000000').valueString()).toEqual('1000000')
|
||||
const fixture = {
|
||||
value: '1',
|
||||
issuer: '0000000000000000000000000000000000000000',
|
||||
currency: 'USD'
|
||||
}
|
||||
const amt = Amount.from(fixture)
|
||||
const rewritten = {
|
||||
value: '1',
|
||||
issuer: 'rrrrrrrrrrrrrrrrrrrrrhoLvTp',
|
||||
currency: 'USD'
|
||||
}
|
||||
expect(amt.toJSON()).toEqual(rewritten)
|
||||
})
|
||||
amountErrorTests()
|
||||
})
|
||||
@@ -1,43 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const fixtures = require('./fixtures/codec-fixtures.json');
|
||||
const {decode, encode, decodeLedgerData} = require('../src');
|
||||
|
||||
function json(object) {
|
||||
return JSON.stringify(object);
|
||||
}
|
||||
|
||||
function truncateForDisplay(longStr) {
|
||||
return longStr.slice(0, 10) + '...' + longStr.slice(-10);
|
||||
}
|
||||
|
||||
describe('ripple-binary-codec', function() {
|
||||
function makeSuite(name, entries) {
|
||||
describe(name, function() {
|
||||
entries.forEach((t, test_n) => {
|
||||
// eslint-disable-next-line max-len
|
||||
it(`${name}[${test_n}] can encode ${truncateForDisplay(json(t.json))} to ${truncateForDisplay(t.binary)}`,
|
||||
() => {
|
||||
assert.equal(t.binary, encode(t.json));
|
||||
});
|
||||
// eslint-disable-next-line max-len
|
||||
it(`${name}[${test_n}] can decode ${truncateForDisplay(t.binary)} to ${truncateForDisplay(json(t.json))}`,
|
||||
() => {
|
||||
const decoded = decode(t.binary);
|
||||
assert.deepEqual(t.json, decoded);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
makeSuite('transactions', fixtures.transactions);
|
||||
makeSuite('accountState', fixtures.accountState);
|
||||
|
||||
describe('ledgerData', function() {
|
||||
fixtures.ledgerData.forEach((t, test_n) => {
|
||||
it(`ledgerData[${test_n}] can decode ${t.binary} to ${json(t.json)}`,
|
||||
() => {
|
||||
const decoded = decodeLedgerData(t.binary);
|
||||
assert.deepEqual(t.json, decoded);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
44
packages/ripple-binary-codec/test/binary-json.test.js
Normal file
44
packages/ripple-binary-codec/test/binary-json.test.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const fixtures = require('./fixtures/codec-fixtures.json')
|
||||
const { decode, encode, decodeLedgerData } = require('../dist')
|
||||
|
||||
function json (object) {
|
||||
return JSON.stringify(object)
|
||||
}
|
||||
|
||||
function truncateForDisplay (longStr) {
|
||||
return longStr.slice(0, 10) + '...' + longStr.slice(-10)
|
||||
}
|
||||
|
||||
describe('ripple-binary-codec', function () {
|
||||
function makeSuite (name, entries) {
|
||||
describe(name, function () {
|
||||
entries.forEach((t, testN) => {
|
||||
// eslint-disable-next-line max-len
|
||||
test(`${name}[${testN}] can encode ${truncateForDisplay(json(t.json))} to ${truncateForDisplay(t.binary)}`,
|
||||
() => {
|
||||
expect(t.binary).toEqual(encode(t.json))
|
||||
})
|
||||
// eslint-disable-next-line max-len
|
||||
test(`${name}[${testN}] can decode ${truncateForDisplay(t.binary)} to ${truncateForDisplay(json(t.json))}`,
|
||||
() => {
|
||||
const decoded = decode(t.binary)
|
||||
expect(t.json).toEqual(decoded)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
makeSuite('transactions', fixtures.transactions)
|
||||
makeSuite('accountState', fixtures.accountState)
|
||||
|
||||
describe('ledgerData', function () {
|
||||
if (fixtures.ledgerData) {
|
||||
fixtures.ledgerData.forEach((t, testN) => {
|
||||
test(`ledgerData[${testN}] can decode ${t.binary} to ${json(t.json)}`,
|
||||
() => {
|
||||
const decoded = decodeLedgerData(t.binary)
|
||||
expect(t.json).toEqual(decoded)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -1,341 +0,0 @@
|
||||
/* 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, Uint8Array.from([0]));
|
||||
assert.deepEqual(parser.read(4), Uint8Array.from([1, 2, 3, 4]));
|
||||
assert.deepEqual(parser.read(2), Uint8Array.from([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);
|
||||
});
|
||||
377
packages/ripple-binary-codec/test/binary-parser.test.js
Normal file
377
packages/ripple-binary-codec/test/binary-parser.test.js
Normal file
@@ -0,0 +1,377 @@
|
||||
/* eslint-disable func-style */
|
||||
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const Decimal = require('decimal.js')
|
||||
|
||||
const _ = require('lodash')
|
||||
const { encodeAccountID } = require('ripple-address-codec')
|
||||
const { binary } = require('../dist/coretypes')
|
||||
const { Amount, Hash160 } = coreTypes
|
||||
const { makeParser, readJSON } = binary
|
||||
const { Enums } = require('./../dist/enums')
|
||||
const Field = Enums.Field
|
||||
const { TransactionType } = Enums
|
||||
const { parseHexOnly, hexOnly, loadFixture } = require('./utils')
|
||||
const { bytesToHex } = require('../dist/utils/bytes-utils')
|
||||
const fixtures = loadFixture('data-driven-tests.json')
|
||||
const { BytesList } = require('../dist/serdes/binary-serializer')
|
||||
|
||||
const __ = hexOnly
|
||||
function unused () {}
|
||||
function toJSON (v) {
|
||||
return v.toJSON ? v.toJSON() : v
|
||||
}
|
||||
|
||||
function assertEqualAmountJSON (actual, expected) {
|
||||
expect((typeof actual) === (typeof expected)).toBe(true)
|
||||
if ((typeof actual) === 'string') {
|
||||
expect(actual).toEqual(expected)
|
||||
return
|
||||
}
|
||||
expect(actual.currency).toEqual(expected.currency)
|
||||
expect(actual.issuer).toEqual(expected.issuer)
|
||||
expect(actual.value === expected.value ||
|
||||
new Decimal(actual.value).equals(
|
||||
new Decimal(expected.value))).toBe(true)
|
||||
}
|
||||
|
||||
function basicApiTests () {
|
||||
const bytes = parseHexOnly('00,01020304,0506', Uint8Array)
|
||||
test('can read slices of bytes', () => {
|
||||
const parser = makeParser(bytes)
|
||||
expect(parser.pos()).toBe(0)
|
||||
expect(parser._buf instanceof Uint8Array).toBe(true)
|
||||
const read1 = parser.read(1)
|
||||
expect(read1 instanceof Uint8Array).toBe(true)
|
||||
expect(read1).toEqual(Uint8Array.from([0]))
|
||||
expect(parser.read(4)).toEqual(Uint8Array.from([1, 2, 3, 4]))
|
||||
expect(parser.read(2)).toEqual(Uint8Array.from([5, 6]))
|
||||
expect(() => parser.read(1)).toThrow()
|
||||
})
|
||||
test('can read a Uint32 at full', () => {
|
||||
const parser = makeParser('FFFFFFFF')
|
||||
expect(parser.readUInt32()).toEqual(0xFFFFFFFF)
|
||||
})
|
||||
}
|
||||
basicApiTests()
|
||||
|
||||
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
|
||||
|
||||
test('can be done with low level apis', () => {
|
||||
const parser = makeParser(transaction.binary)
|
||||
|
||||
expect(parser.readField()).toEqual(Field.TransactionType)
|
||||
expect(parser.readUInt16()).toEqual(7)
|
||||
expect(parser.readField()).toEqual(Field.Flags)
|
||||
expect(parser.readUInt32()).toEqual(0)
|
||||
expect(parser.readField()).toEqual(Field.Sequence)
|
||||
expect(parser.readUInt32()).toEqual(103929)
|
||||
expect(parser.readField()).toEqual(Field.TakerPays)
|
||||
parser.read(8)
|
||||
expect(parser.readField()).toEqual(Field.TakerGets)
|
||||
// amount value
|
||||
expect(parser.read(8)).not.toBe([])
|
||||
// amount currency
|
||||
expect(Hash160.fromParser(parser)).not.toBe([])
|
||||
expect(encodeAccountID(parser.read(20))).toEqual(tx_json.TakerGets.issuer)
|
||||
expect(parser.readField()).toEqual(Field.Fee)
|
||||
expect(parser.read(8)).not.toEqual([])
|
||||
expect(parser.readField()).toEqual(Field.SigningPubKey)
|
||||
expect(parser.readVLLength()).toBe(33)
|
||||
expect(bytesToHex(parser.read(33))).toEqual(tx_json.SigningPubKey)
|
||||
expect(parser.readField()).toEqual(Field.TxnSignature)
|
||||
expect(bytesToHex(parser.readVL())).toEqual(tx_json.TxnSignature)
|
||||
expect(parser.readField()).toEqual(Field.Account)
|
||||
expect(encodeAccountID(parser.readVL())).toEqual(tx_json.Account)
|
||||
expect(parser.end()).toBe(true)
|
||||
})
|
||||
|
||||
test('can be done with high level apis', () => {
|
||||
const parser = makeParser(transaction.binary)
|
||||
function readField () {
|
||||
return parser.readFieldAndValue()
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.TransactionType)
|
||||
expect(value).toEqual(TransactionType.OfferCreate)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.Flags)
|
||||
expect(value.val).toEqual(0)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.Sequence)
|
||||
expect(value.val).toEqual(103929)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.TakerPays)
|
||||
expect(value.currency.isNative()).toEqual(true)
|
||||
expect(value.currency.toJSON()).toEqual('XRP')
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.TakerGets)
|
||||
expect(value.currency.isNative()).toEqual(false)
|
||||
expect(value.issuer.toJSON()).toEqual(tx_json.TakerGets.issuer)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.Fee)
|
||||
expect(value.currency.isNative()).toEqual(true)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.SigningPubKey)
|
||||
expect(value.toJSON()).toEqual(tx_json.SigningPubKey)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.TxnSignature)
|
||||
expect(value.toJSON()).toEqual(tx_json.TxnSignature)
|
||||
}
|
||||
{
|
||||
const [field, value] = readField()
|
||||
expect(field).toEqual(Field.Account)
|
||||
expect(value.toJSON()).toEqual(tx_json.Account)
|
||||
}
|
||||
expect(parser.end()).toBe(true)
|
||||
})
|
||||
|
||||
test('can be done with higher level apis', () => {
|
||||
const parser = makeParser(transaction.binary)
|
||||
const jsonFromBinary = readJSON(parser)
|
||||
expect(jsonFromBinary).toEqual(tx_json)
|
||||
})
|
||||
|
||||
test('readJSON (binary.decode) does not return STObject ', () => {
|
||||
const parser = makeParser(transaction.binary)
|
||||
const jsonFromBinary = readJSON(parser)
|
||||
expect(jsonFromBinary instanceof coreTypes.STObject).toBe(false)
|
||||
expect(_.isPlainObject(jsonFromBinary)).toBe(true)
|
||||
})
|
||||
}
|
||||
transactionParsingTests()
|
||||
|
||||
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)}`
|
||||
test(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) {
|
||||
expect(value.exponent()).toEqual(f.exponent)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
amountParsingTests()
|
||||
|
||||
function fieldParsingTests () {
|
||||
fixtures.fields_tests.forEach((f, i) => {
|
||||
const parser = makeParser(f.expected_hex)
|
||||
test(`fields[${i}]: parses ${f.expected_hex} as ${f.name}`, () => {
|
||||
const field = parser.readField()
|
||||
expect(field.name).toEqual(f.name)
|
||||
expect(field.type.name).toEqual(f.type_name)
|
||||
})
|
||||
})
|
||||
}
|
||||
fieldParsingTests()
|
||||
|
||||
function assertRecyclable (json, forField) {
|
||||
const Type = forField.associatedType
|
||||
const recycled = Type.from(json).toJSON()
|
||||
expect(recycled).toEqual(json)
|
||||
const sink = new BytesList()
|
||||
Type.from(recycled).toBytesSink(sink)
|
||||
const recycledAgain = makeParser(sink.toHex())
|
||||
.readType(Type)
|
||||
.toJSON()
|
||||
expect(recycledAgain).toEqual(json)
|
||||
}
|
||||
|
||||
function nestedObjectTests () {
|
||||
function disabled (i) {
|
||||
unused(i)
|
||||
return false // !_.includes([2], i);
|
||||
}
|
||||
|
||||
fixtures.whole_objects.forEach((f, i) => {
|
||||
if (disabled(i)) {
|
||||
return
|
||||
}
|
||||
|
||||
test(`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 {
|
||||
expect(actual).toEqual(expectedJSON)
|
||||
} catch (e) {
|
||||
throw new Error(`${e} ${field} a: ${actual} e: ${expectedJSON}`)
|
||||
}
|
||||
expect(field.name).toEqual(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'
|
||||
}]]
|
||||
|
||||
test('works with long paths', () => {
|
||||
const parser = makeParser(bytes)
|
||||
const txn = readJSON(parser)
|
||||
expect(txn.Paths).toEqual(expectedJSON)
|
||||
// TODO: this should go elsewhere
|
||||
expect(
|
||||
coreTypes.PathSet.from(txn.Paths).toJSON()).toEqual(
|
||||
expectedJSON
|
||||
)
|
||||
})
|
||||
}
|
||||
pathSetBinaryTests()
|
||||
|
||||
describe('Binary Parser', function() {
|
||||
describe('pathSetBinaryTests', pathSetBinaryTests);
|
||||
describe('nestedObjectTests', nestedObjectTests);
|
||||
});
|
||||
@@ -1,194 +0,0 @@
|
||||
/* eslint-disable func-style */
|
||||
|
||||
const BN = require('bn.js');
|
||||
const assert = require('assert');
|
||||
const lib = require('../src/coretypes');
|
||||
const encode = require('../src').encode;
|
||||
const {binary: {makeParser, BytesList, BinarySerializer}} = lib;
|
||||
const {UInt8, UInt16, UInt32, UInt64, STObject} = lib;
|
||||
const {loadFixture} = require('./utils');
|
||||
const fixtures = loadFixture('data-driven-tests.json');
|
||||
const deliverMinTx = require('./fixtures/delivermin-tx.json');
|
||||
const deliverMinTxBinary = require('./fixtures/delivermin-tx-binary.json');
|
||||
const SignerListSet = {
|
||||
tx: require('./fixtures/signerlistset-tx.json'),
|
||||
binary: require('./fixtures/signerlistset-tx-binary.json'),
|
||||
meta: require('./fixtures/signerlistset-tx-meta-binary.json')
|
||||
};
|
||||
const DepositPreauth = {
|
||||
tx: require('./fixtures/deposit-preauth-tx.json'),
|
||||
binary: require('./fixtures/deposit-preauth-tx-binary.json'),
|
||||
meta: require('./fixtures/deposit-preauth-tx-meta-binary.json')
|
||||
};
|
||||
const Escrow = {
|
||||
create: {
|
||||
tx: require('./fixtures/escrow-create-tx.json'),
|
||||
binary: require('./fixtures/escrow-create-binary.json')
|
||||
},
|
||||
finish: {
|
||||
tx: require('./fixtures/escrow-finish-tx.json'),
|
||||
binary: require('./fixtures/escrow-finish-binary.json'),
|
||||
meta: require('./fixtures/escrow-finish-meta-binary.json')
|
||||
},
|
||||
cancel: {
|
||||
tx: require('./fixtures/escrow-cancel-tx.json'),
|
||||
binary: require('./fixtures/escrow-cancel-binary.json')
|
||||
}
|
||||
}
|
||||
const PaymentChannel = {
|
||||
create: {
|
||||
tx: require('./fixtures/payment-channel-create-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-create-binary.json')
|
||||
},
|
||||
fund: {
|
||||
tx: require('./fixtures/payment-channel-fund-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-fund-binary.json')
|
||||
},
|
||||
claim: {
|
||||
tx: require('./fixtures/payment-channel-claim-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-claim-binary.json')
|
||||
}
|
||||
}
|
||||
|
||||
function bytesListTest() {
|
||||
const list = new BytesList().put([0]).put([2, 3]).put([4, 5]);
|
||||
it('is an Array<Uint8Array>', function() {
|
||||
assert(Array.isArray(list.arrays));
|
||||
assert(list.arrays[0] instanceof Uint8Array);
|
||||
});
|
||||
it('keeps track of the length itself', function() {
|
||||
assert.equal(list.length, 5);
|
||||
});
|
||||
it('can join all arrays into one via toBytes', function() {
|
||||
const joined = list.toBytes();
|
||||
assert(joined.length, 5);
|
||||
assert.deepEqual(joined, Uint8Array.from([0, 2, 3, 4, 5]));
|
||||
});
|
||||
}
|
||||
|
||||
function assertRecycles(blob) {
|
||||
const parser = makeParser(blob);
|
||||
const so = parser.readType(STObject);
|
||||
const out = new BytesList();
|
||||
so.toBytesSink(out);
|
||||
const hex = out.toHex();
|
||||
assert.equal(hex, blob);
|
||||
assert.notEqual(hex + ':', blob);
|
||||
}
|
||||
|
||||
function nestedObjectTests() {
|
||||
fixtures.whole_objects.forEach((f, i) => {
|
||||
it(`whole_objects[${i}]: can parse blob and dump out same blob`,
|
||||
/* */ () => {
|
||||
assertRecycles(f.blob_with_no_signing);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function UIntTest() {
|
||||
function check(type, n, expected) {
|
||||
it(`Uint${type.width * 8} serializes ${n} as ${expected}`, function() {
|
||||
const bl = new BytesList();
|
||||
const serializer = new BinarySerializer(bl);
|
||||
if (expected === 'throws') {
|
||||
assert.throws(() => serializer.writeType(type, n));
|
||||
return;
|
||||
}
|
||||
serializer.writeType(type, n);
|
||||
assert.deepEqual(bl.toBytes(), Uint8Array.from(expected));
|
||||
});
|
||||
}
|
||||
|
||||
check(UInt8, 5, [5]);
|
||||
check(UInt16, 5, [0, 5]);
|
||||
check(UInt32, 5, [0, 0, 0, 5]);
|
||||
check(UInt32, 0xFFFFFFFF, [255, 255, 255, 255]);
|
||||
check(UInt8, 0xFEFFFFFF, 'throws');
|
||||
check(UInt16, 0xFEFFFFFF, 'throws');
|
||||
check(UInt16, 0xFEFFFFFF, 'throws');
|
||||
check(UInt64, 0xFEFFFFFF, [0, 0, 0, 0, 254, 255, 255, 255]);
|
||||
check(UInt64, -1, 'throws');
|
||||
check(UInt64, 0, [0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
check(UInt64, 1, [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
check(UInt64, new BN(1), [0, 0, 0, 0, 0, 0, 0, 1]);
|
||||
}
|
||||
|
||||
|
||||
function parseLedger4320278() {
|
||||
it('can parse object', done => {
|
||||
this.timeout(30e3);
|
||||
const json = loadFixture('as-ledger-4320278.json');
|
||||
json.forEach(e => {
|
||||
assertRecycles(e.binary);
|
||||
});
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function deliverMinTest() {
|
||||
it('can serialize DeliverMin', () => {
|
||||
assert.strictEqual(encode(deliverMinTx), deliverMinTxBinary);
|
||||
});
|
||||
}
|
||||
|
||||
function SignerListSetTest() {
|
||||
it('can serialize SignerListSet', () => {
|
||||
assert.strictEqual(encode(SignerListSet.tx), SignerListSet.binary);
|
||||
});
|
||||
it('can serialize SignerListSet metadata', () => {
|
||||
assert.strictEqual(encode(SignerListSet.tx.meta), SignerListSet.meta);
|
||||
});
|
||||
}
|
||||
|
||||
function DepositPreauthTest() {
|
||||
it('can serialize DepositPreauth', () => {
|
||||
assert.strictEqual(encode(DepositPreauth.tx), DepositPreauth.binary);
|
||||
});
|
||||
it('can serialize DepositPreauth metadata', () => {
|
||||
assert.strictEqual(encode(DepositPreauth.tx.meta), DepositPreauth.meta);
|
||||
});
|
||||
}
|
||||
|
||||
function EscrowTest() {
|
||||
it('can serialize EscrowCreate', () => {
|
||||
assert.strictEqual(encode(Escrow.create.tx),
|
||||
Escrow.create.binary);
|
||||
});
|
||||
it('can serialize EscrowFinish', () => {
|
||||
assert.strictEqual(encode(Escrow.finish.tx),
|
||||
Escrow.finish.binary);
|
||||
assert.strictEqual(encode(Escrow.finish.tx.meta),
|
||||
Escrow.finish.meta);
|
||||
});
|
||||
it('can serialize EscrowCancel', () => {
|
||||
assert.strictEqual(encode(Escrow.cancel.tx),
|
||||
Escrow.cancel.binary);
|
||||
});
|
||||
}
|
||||
|
||||
function PaymentChannelTest() {
|
||||
it('can serialize PaymentChannelCreate', () => {
|
||||
assert.strictEqual(encode(PaymentChannel.create.tx),
|
||||
PaymentChannel.create.binary);
|
||||
});
|
||||
it('can serialize PaymentChannelFund', () => {
|
||||
assert.strictEqual(encode(PaymentChannel.fund.tx),
|
||||
PaymentChannel.fund.binary);
|
||||
});
|
||||
it('can serialize PaymentChannelClaim', () => {
|
||||
assert.strictEqual(encode(PaymentChannel.claim.tx),
|
||||
PaymentChannel.claim.binary);
|
||||
});
|
||||
}
|
||||
|
||||
describe('Binary Serialization', function() {
|
||||
describe.skip('parseLedger4320278', parseLedger4320278);
|
||||
describe('nestedObjectTests', nestedObjectTests);
|
||||
describe('UIntTest', UIntTest);
|
||||
describe('BytesList', bytesListTest);
|
||||
describe('DeliverMin', deliverMinTest);
|
||||
describe('DepositPreauth', DepositPreauthTest);
|
||||
describe('SignerListSet', SignerListSetTest);
|
||||
describe('Escrow', EscrowTest);
|
||||
describe('PaymentChannel', PaymentChannelTest);
|
||||
});
|
||||
183
packages/ripple-binary-codec/test/binary-serializer.test.js
Normal file
183
packages/ripple-binary-codec/test/binary-serializer.test.js
Normal file
@@ -0,0 +1,183 @@
|
||||
/* eslint-disable func-style */
|
||||
|
||||
const { BN } = require('bn.js')
|
||||
const { binary } = require('../dist/coretypes')
|
||||
const { encode } = require('../dist')
|
||||
const { makeParser, BytesList, BinarySerializer } = binary
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { UInt8, UInt16, UInt32, UInt64, STObject } = coreTypes
|
||||
|
||||
const { loadFixture } = require('./utils')
|
||||
const fixtures = loadFixture('data-driven-tests.json')
|
||||
const deliverMinTx = require('./fixtures/delivermin-tx.json')
|
||||
const deliverMinTxBinary = require('./fixtures/delivermin-tx-binary.json')
|
||||
const SignerListSet = {
|
||||
tx: require('./fixtures/signerlistset-tx.json'),
|
||||
binary: require('./fixtures/signerlistset-tx-binary.json'),
|
||||
meta: require('./fixtures/signerlistset-tx-meta-binary.json')
|
||||
}
|
||||
const DepositPreauth = {
|
||||
tx: require('./fixtures/deposit-preauth-tx.json'),
|
||||
binary: require('./fixtures/deposit-preauth-tx-binary.json'),
|
||||
meta: require('./fixtures/deposit-preauth-tx-meta-binary.json')
|
||||
}
|
||||
const Escrow = {
|
||||
create: {
|
||||
tx: require('./fixtures/escrow-create-tx.json'),
|
||||
binary: require('./fixtures/escrow-create-binary.json')
|
||||
},
|
||||
finish: {
|
||||
tx: require('./fixtures/escrow-finish-tx.json'),
|
||||
binary: require('./fixtures/escrow-finish-binary.json'),
|
||||
meta: require('./fixtures/escrow-finish-meta-binary.json')
|
||||
},
|
||||
cancel: {
|
||||
tx: require('./fixtures/escrow-cancel-tx.json'),
|
||||
binary: require('./fixtures/escrow-cancel-binary.json')
|
||||
}
|
||||
}
|
||||
const PaymentChannel = {
|
||||
create: {
|
||||
tx: require('./fixtures/payment-channel-create-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-create-binary.json')
|
||||
},
|
||||
fund: {
|
||||
tx: require('./fixtures/payment-channel-fund-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-fund-binary.json')
|
||||
},
|
||||
claim: {
|
||||
tx: require('./fixtures/payment-channel-claim-tx.json'),
|
||||
binary: require('./fixtures/payment-channel-claim-binary.json')
|
||||
}
|
||||
}
|
||||
|
||||
function bytesListTest () {
|
||||
const list = new BytesList().put([0]).put([2, 3]).put([4, 5])
|
||||
test('is an Array<Uint8Array>', function () {
|
||||
expect(Array.isArray(list.arrays)).toBe(true)
|
||||
expect(list.arrays[0] instanceof Uint8Array).toBe(true)
|
||||
})
|
||||
test('keeps track of the length itself', function () {
|
||||
expect(list).toHaveLength(5)
|
||||
})
|
||||
test('can join all arrays into one via toBytes', function () {
|
||||
const joined = list.toBytes()
|
||||
expect(joined).toHaveLength(5)
|
||||
expect(joined).toEqual(Uint8Array.from([0, 2, 3, 4, 5]))
|
||||
})
|
||||
}
|
||||
|
||||
function assertRecycles (blob) {
|
||||
const parser = makeParser(blob)
|
||||
const so = parser.readType(STObject)
|
||||
const out = new BytesList()
|
||||
so.toBytesSink(out)
|
||||
const hex = out.toHex()
|
||||
expect(hex).toEqual(blob)
|
||||
expect(hex + ':').not.toEqual(blob)
|
||||
}
|
||||
|
||||
function nestedObjectTests () {
|
||||
fixtures.whole_objects.forEach((f, i) => {
|
||||
test(`whole_objects[${i}]: can parse blob and dump out same blob`,
|
||||
/* */ () => {
|
||||
assertRecycles(f.blob_with_no_signing)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function check (type, n, expected) {
|
||||
test(`Uint${type.width * 8} serializes ${n} as ${expected}`, function () {
|
||||
const bl = new BytesList()
|
||||
const serializer = new BinarySerializer(bl)
|
||||
if (expected === 'throws') {
|
||||
expect(() => serializer.writeType(type, n)).toThrow()
|
||||
return
|
||||
}
|
||||
serializer.writeType(type, n)
|
||||
expect(bl.toBytes()).toEqual(Uint8Array.from(expected))
|
||||
})
|
||||
}
|
||||
|
||||
check(UInt8, 5, [5])
|
||||
check(UInt16, 5, [0, 5])
|
||||
check(UInt32, 5, [0, 0, 0, 5])
|
||||
check(UInt32, 0xFFFFFFFF, [255, 255, 255, 255])
|
||||
check(UInt8, 0xFEFFFFFF, 'throws')
|
||||
check(UInt16, 0xFEFFFFFF, 'throws')
|
||||
check(UInt16, 0xFEFFFFFF, 'throws')
|
||||
check(UInt64, 0xFEFFFFFF, [0, 0, 0, 0, 254, 255, 255, 255])
|
||||
check(UInt64, -1, 'throws')
|
||||
check(UInt64, 0, [0, 0, 0, 0, 0, 0, 0, 0])
|
||||
check(UInt64, 1, [0, 0, 0, 0, 0, 0, 0, 1])
|
||||
check(UInt64, new BN(1), [0, 0, 0, 0, 0, 0, 0, 1])
|
||||
|
||||
// function parseLedger4320278() {
|
||||
// test('can parse object', done => {
|
||||
// const json = loadFixture('as-ledger-4320278.json');
|
||||
// json.forEach(e => {
|
||||
// assertRecycles(e.binary);
|
||||
// });
|
||||
// done();
|
||||
// });
|
||||
// }
|
||||
// parseLedger4320278();
|
||||
|
||||
function deliverMinTest () {
|
||||
test('can serialize DeliverMin', () => {
|
||||
expect(encode(deliverMinTx)).toEqual(deliverMinTxBinary)
|
||||
})
|
||||
}
|
||||
|
||||
function SignerListSetTest () {
|
||||
test('can serialize SignerListSet', () => {
|
||||
expect(encode(SignerListSet.tx)).toEqual(SignerListSet.binary)
|
||||
})
|
||||
test('can serialize SignerListSet metadata', () => {
|
||||
expect(encode(SignerListSet.tx.meta)).toEqual(SignerListSet.meta)
|
||||
})
|
||||
}
|
||||
|
||||
function DepositPreauthTest () {
|
||||
test('can serialize DepositPreauth', () => {
|
||||
expect(encode(DepositPreauth.tx)).toEqual(DepositPreauth.binary)
|
||||
})
|
||||
test('can serialize DepositPreauth metadata', () => {
|
||||
expect(encode(DepositPreauth.tx.meta)).toEqual(DepositPreauth.meta)
|
||||
})
|
||||
}
|
||||
|
||||
function EscrowTest () {
|
||||
test('can serialize EscrowCreate', () => {
|
||||
expect(encode(Escrow.create.tx)).toEqual(Escrow.create.binary)
|
||||
})
|
||||
test('can serialize EscrowFinish', () => {
|
||||
expect(encode(Escrow.finish.tx)).toEqual(Escrow.finish.binary)
|
||||
expect(encode(Escrow.finish.tx.meta)).toEqual(Escrow.finish.meta)
|
||||
})
|
||||
test('can serialize EscrowCancel', () => {
|
||||
expect(encode(Escrow.cancel.tx)).toEqual(Escrow.cancel.binary)
|
||||
})
|
||||
}
|
||||
|
||||
function PaymentChannelTest () {
|
||||
test('can serialize PaymentChannelCreate', () => {
|
||||
expect(encode(PaymentChannel.create.tx)).toEqual(PaymentChannel.create.binary)
|
||||
})
|
||||
test('can serialize PaymentChannelFund', () => {
|
||||
expect(encode(PaymentChannel.fund.tx)).toEqual(PaymentChannel.fund.binary)
|
||||
})
|
||||
test('can serialize PaymentChannelClaim', () => {
|
||||
expect(encode(PaymentChannel.claim.tx)).toEqual(PaymentChannel.claim.binary)
|
||||
})
|
||||
}
|
||||
|
||||
describe('Binary Serialization', function() {
|
||||
describe('nestedObjectTests', nestedObjectTests);
|
||||
describe('BytesList', bytesListTest);
|
||||
describe('DeliverMin', deliverMinTest);
|
||||
describe('DepositPreauth', DepositPreauthTest);
|
||||
describe('SignerListSet', SignerListSetTest);
|
||||
describe('Escrow', EscrowTest);
|
||||
describe('PaymentChannel', PaymentChannelTest);
|
||||
})
|
||||
@@ -1,72 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const bytesUtils = require('../src/utils/bytes-utils');
|
||||
const {slice, compareBytes, parseBytes, bytesToHex} = bytesUtils;
|
||||
|
||||
describe('bytes-utils', function() {
|
||||
describe('parseBytes', function() {
|
||||
it('can decode hex', function() {
|
||||
assert.deepEqual(parseBytes('0012'), [0x00, 0x12]);
|
||||
assert.deepEqual(parseBytes('0012'), [0x00, 0x12]);
|
||||
assert.deepEqual(parseBytes('00AA'), [0x00, 0xaa]);
|
||||
});
|
||||
it('can decode hex to a Uint8Array', function() {
|
||||
const result = parseBytes('0012', Uint8Array);
|
||||
assert(result instanceof Uint8Array);
|
||||
assert.deepEqual(result, Uint8Array.from([0x00, 0x12]));
|
||||
});
|
||||
it('can convert a list to a Uint8Array', function() {
|
||||
const result = parseBytes([0x00, 0x12], Uint8Array);
|
||||
assert(result instanceof Uint8Array);
|
||||
assert.deepEqual(result, Uint8Array.from([0x00, 0x12]));
|
||||
});
|
||||
it('can decode hex to a Buffer', function() {
|
||||
const result = parseBytes('0012', Buffer);
|
||||
assert(result instanceof Buffer);
|
||||
assert.deepEqual(result.toJSON().data, [0x00, 0x12]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bytesToHex', function() {
|
||||
it('can encode an array as hex', function() {
|
||||
assert.deepEqual(bytesToHex([0x00, 0xaa]), '00AA');
|
||||
assert.deepEqual(bytesToHex([0xaa]), 'AA');
|
||||
});
|
||||
it('can encode Uint8Array as hex', function() {
|
||||
assert.deepEqual(bytesToHex(new Uint8Array([0x00, 0xaa])), '00AA');
|
||||
assert.deepEqual(bytesToHex(new Uint8Array([0xaa])), 'AA');
|
||||
});
|
||||
});
|
||||
|
||||
describe('compareBytes', function() {
|
||||
it('compares the bytes sequence as big endian number', function() {
|
||||
assert.equal(compareBytes([0, 1, 2], [1, 2, 3]), -1);
|
||||
});
|
||||
it('throws when the bytes sequences are of unlike length', function() {
|
||||
assert.throws(() => compareBytes([0, 1], [1]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('slice', function() {
|
||||
const val = [1, 2, 3, 4, 5];
|
||||
it('creates a slice of the same type as first arg', function() {
|
||||
assert(Array.isArray(slice(val)));
|
||||
});
|
||||
it('the 2nd arg is the start position [2:]', function() {
|
||||
assert.deepEqual(val.slice(2), [3, 4, 5]);
|
||||
assert.deepEqual(slice(val, 2), [3, 4, 5]);
|
||||
});
|
||||
it('the 3rd arg is the end position [2:4]', function() {
|
||||
assert.deepEqual(slice(val, 2, 4), [3, 4]);
|
||||
});
|
||||
it('can slice using negative numbers [-3:]', function() {
|
||||
assert.deepEqual(slice(val, -3), [3, 4, 5]);
|
||||
});
|
||||
it('can slice using negative numbers [-3:-1]', function() {
|
||||
assert.deepEqual(slice(val, -3, -1), [3, 4]);
|
||||
});
|
||||
it('the 4th arg is the output class type', function() {
|
||||
assert.deepEqual(slice(val, 2, 4, Buffer).toJSON().data, [3, 4]);
|
||||
assert.deepEqual(slice(val, 2, 4, Uint8Array), Uint8Array.from([3, 4]));
|
||||
});
|
||||
});
|
||||
});
|
||||
70
packages/ripple-binary-codec/test/bytes-utils.test.js
Normal file
70
packages/ripple-binary-codec/test/bytes-utils.test.js
Normal file
@@ -0,0 +1,70 @@
|
||||
const { slice, compareBytes, parseBytes, bytesToHex } = require('../dist/utils/bytes-utils')
|
||||
|
||||
describe('bytes-utils', function () {
|
||||
describe('parseBytes', function () {
|
||||
test('can decode hex', function () {
|
||||
expect(parseBytes('0012')).toEqual([0x00, 0x12])
|
||||
expect(parseBytes('0012')).toEqual([0x00, 0x12])
|
||||
expect(parseBytes('00AA')).toEqual([0x00, 0xaa])
|
||||
})
|
||||
test('can decode hex to a Uint8Array', function () {
|
||||
const result = parseBytes('0012', Uint8Array)
|
||||
expect(result instanceof Uint8Array).toBe(true)
|
||||
expect(result).toEqual(Uint8Array.from([0x00, 0x12]))
|
||||
})
|
||||
test('can convert a list to a Uint8Array', function () {
|
||||
const result = parseBytes([0x00, 0x12], Uint8Array)
|
||||
expect(result instanceof Uint8Array).toBe(true)
|
||||
expect(result).toEqual(Uint8Array.from([0x00, 0x12]))
|
||||
})
|
||||
test('can decode hex to a Buffer', function () {
|
||||
const result = parseBytes('0012', Buffer)
|
||||
expect(result instanceof Buffer).toBe(true)
|
||||
expect(result.toJSON().data).toEqual([0x00, 0x12])
|
||||
})
|
||||
})
|
||||
|
||||
describe('bytesToHex', function () {
|
||||
test('can encode an array as hex', function () {
|
||||
expect(bytesToHex([0x00, 0xaa])).toBe('00AA')
|
||||
expect(bytesToHex([0xaa])).toBe('AA')
|
||||
})
|
||||
test('can encode Uint8Array as hex', function () {
|
||||
expect(bytesToHex(new Uint8Array([0x00, 0xaa]))).toBe('00AA')
|
||||
expect(bytesToHex(new Uint8Array([0xaa]))).toBe('AA')
|
||||
})
|
||||
})
|
||||
|
||||
describe('compareBytes', function () {
|
||||
test('compares the bytes sequence as big endian number', function () {
|
||||
expect(compareBytes([0, 1, 2], [1, 2, 3])).toBe(-1)
|
||||
})
|
||||
test('throws when the bytes sequences are of unlike length', function () {
|
||||
expect(() => compareBytes([0, 1], [1])).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe('slice', function () {
|
||||
const val = [1, 2, 3, 4, 5]
|
||||
test('creates a slice of the same type as first arg', function () {
|
||||
expect(Array.isArray(slice(val))).toBe(true)
|
||||
})
|
||||
test('the 2nd arg is the start position [2:]', function () {
|
||||
expect(val.slice(2)).toEqual([3, 4, 5])
|
||||
expect(slice(val, 2)).toEqual([3, 4, 5])
|
||||
})
|
||||
test('the 3rd arg is the end position [2:4]', function () {
|
||||
expect(slice(val, 2, 4)).toEqual([3, 4])
|
||||
})
|
||||
test('can slice using negative numbers [-3:]', function () {
|
||||
expect(slice(val, -3)).toEqual([3, 4, 5])
|
||||
})
|
||||
test('can slice using negative numbers [-3:-1]', function () {
|
||||
expect(slice(val, -3, -1)).toEqual([3, 4])
|
||||
})
|
||||
test('the 4th arg is the output class type', function () {
|
||||
expect(slice(val, 2, 4, Buffer).toJSON().data).toEqual([3, 4])
|
||||
expect(slice(val, 2, 4, Uint8Array)).toEqual(Uint8Array.from([3, 4]))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -3718,4 +3718,4 @@
|
||||
"expected_hex": "8D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const {Hash160, Hash256, Currency, AccountID} = require('../src/coretypes');
|
||||
|
||||
describe('Hash160', function() {
|
||||
it('has a static width membmer', function() {
|
||||
assert.equal(Hash160.width, 20);
|
||||
});
|
||||
it('inherited by subclasses', function() {
|
||||
assert.equal(AccountID.width, 20);
|
||||
assert.equal(Currency.width, 20);
|
||||
});
|
||||
it('can be compared against another', function() {
|
||||
const h1 = Hash160.from('1000000000000000000000000000000000000000');
|
||||
const h2 = Hash160.from('2000000000000000000000000000000000000000');
|
||||
const h3 = Hash160.from('0000000000000000000000000000000000000003');
|
||||
assert(h1.lt(h2));
|
||||
assert(h3.lt(h2));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hash256', function() {
|
||||
it('has a static width membmer', function() {
|
||||
assert.equal(Hash256.width, 32);
|
||||
});
|
||||
it('has a ZERO_256 member', function() {
|
||||
assert.equal(
|
||||
Hash256.ZERO_256.toJSON(),
|
||||
'0000000000000000000000000000000000000000000000000000000000000000');
|
||||
});
|
||||
it('supports getting the nibblet values at given positions', function() {
|
||||
const h = Hash256.from(
|
||||
'1359BD0000000000000000000000000000000000000000000000000000000000');
|
||||
assert.equal(h.nibblet(0), 0x1);
|
||||
assert.equal(h.nibblet(1), 0x3);
|
||||
assert.equal(h.nibblet(2), 0x5);
|
||||
assert.equal(h.nibblet(3), 0x9);
|
||||
assert.equal(h.nibblet(4), 0x0b);
|
||||
assert.equal(h.nibblet(5), 0xd);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Currency', function() {
|
||||
it('Will have a null iso() for dodgy XRP ', function() {
|
||||
const bad = Currency.from('0000000000000000000000005852500000000000');
|
||||
assert.equal(bad.iso(), null);
|
||||
assert.equal(bad.isNative(), false);
|
||||
});
|
||||
it('can be constructed from an Array', function() {
|
||||
const xrp = Currency.from(new Uint8Array(20));
|
||||
assert.equal(xrp.iso(), 'XRP');
|
||||
});
|
||||
it('throws on invalid reprs', function() {
|
||||
assert.throws(() => Currency.from(new Uint8Array(19)));
|
||||
assert.throws(() => Currency.from(1));
|
||||
assert.throws(() => Currency.from(
|
||||
'00000000000000000000000000000000000000m'));
|
||||
});
|
||||
});
|
||||
56
packages/ripple-binary-codec/test/hash.test.js
Normal file
56
packages/ripple-binary-codec/test/hash.test.js
Normal file
@@ -0,0 +1,56 @@
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { Hash160, Hash256, Currency, AccountID } = coreTypes
|
||||
|
||||
describe('Hash160', function () {
|
||||
test('has a static width membmer', function () {
|
||||
expect(Hash160.width).toBe(20)
|
||||
})
|
||||
test('inherited by subclasses', function () {
|
||||
expect(AccountID.width).toBe(20)
|
||||
expect(Currency.width).toBe(20)
|
||||
})
|
||||
test('can be compared against another', function () {
|
||||
const h1 = Hash160.from('1000000000000000000000000000000000000000')
|
||||
const h2 = Hash160.from('2000000000000000000000000000000000000000')
|
||||
const h3 = Hash160.from('0000000000000000000000000000000000000003')
|
||||
expect(h1.lt(h2)).toBe(true)
|
||||
expect(h3.lt(h2)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Hash256', function () {
|
||||
test('has a static width membmer', function () {
|
||||
expect(Hash256.width).toBe(32)
|
||||
})
|
||||
test('has a ZERO_256 member', function () {
|
||||
expect(Hash256.ZERO_256.toJSON()).toBe('0000000000000000000000000000000000000000000000000000000000000000')
|
||||
})
|
||||
test('supports getting the nibblet values at given positions', function () {
|
||||
const h = Hash256.from(
|
||||
'1359BD0000000000000000000000000000000000000000000000000000000000')
|
||||
expect(h.nibblet(0)).toBe(0x1)
|
||||
expect(h.nibblet(1)).toBe(0x3)
|
||||
expect(h.nibblet(2)).toBe(0x5)
|
||||
expect(h.nibblet(3)).toBe(0x9)
|
||||
expect(h.nibblet(4)).toBe(0x0b)
|
||||
expect(h.nibblet(5)).toBe(0xd)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Currency', function () {
|
||||
test('Will have a null iso() for dodgy XRP ', function () {
|
||||
const bad = Currency.from('0000000000000000000000005852500000000000')
|
||||
expect(bad.iso()).toBeNull()
|
||||
expect(bad.isNative()).toBe(false)
|
||||
})
|
||||
test('can be constructed from an Array', function () {
|
||||
const xrp = Currency.from(new Uint8Array(20))
|
||||
expect(xrp.iso()).toBe('XRP')
|
||||
})
|
||||
test('throws on invalid reprs', function () {
|
||||
expect(() => Currency.from(new Uint8Array(19))).toThrow()
|
||||
expect(() => Currency.from(1)).toThrow()
|
||||
expect(() => Currency.from(
|
||||
'00000000000000000000000000000000000000m')).toThrow()
|
||||
})
|
||||
})
|
||||
@@ -1,26 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const {loadFixture} = require('./utils');
|
||||
const ledgerHashes = require('../src/ledger-hashes');
|
||||
const {transactionTreeHash, ledgerHash, accountStateHash} = ledgerHashes;
|
||||
|
||||
describe('Ledger Hashes', function() {
|
||||
function testFactory(ledgerFixture) {
|
||||
describe(`can calculate hashes for ${ledgerFixture}`, function() {
|
||||
const ledger = loadFixture(ledgerFixture);
|
||||
it('computes correct account state hash', function() {
|
||||
assert.equal(accountStateHash(ledger.accountState).toHex(),
|
||||
ledger.account_hash);
|
||||
});
|
||||
it('computes correct transaction tree hash', function() {
|
||||
assert.equal(transactionTreeHash(ledger.transactions).toHex(),
|
||||
ledger.transaction_hash);
|
||||
});
|
||||
it('computes correct ledger header hash', function() {
|
||||
assert.equal(ledgerHash(ledger).toHex(), ledger.hash);
|
||||
});
|
||||
});
|
||||
}
|
||||
testFactory('ledger-full-40000.json');
|
||||
testFactory('ledger-full-38129.json');
|
||||
});
|
||||
|
||||
21
packages/ripple-binary-codec/test/ledger.test.js
Normal file
21
packages/ripple-binary-codec/test/ledger.test.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const { loadFixture } = require('./utils')
|
||||
const { transactionTreeHash, ledgerHash, accountStateHash } = require('../dist/ledger-hashes')
|
||||
|
||||
describe('Ledger Hashes', function () {
|
||||
function testFactory (ledgerFixture) {
|
||||
describe(`can calculate hashes for ${ledgerFixture}`, function () {
|
||||
const ledger = loadFixture(ledgerFixture)
|
||||
test('computes correct account state hash', function () {
|
||||
expect(accountStateHash(ledger.accountState).toHex()).toBe(ledger.account_hash)
|
||||
})
|
||||
test('computes correct transaction tree hash', function () {
|
||||
expect(transactionTreeHash(ledger.transactions).toHex()).toBe(ledger.transaction_hash)
|
||||
})
|
||||
test('computes correct ledger header hash', function () {
|
||||
expect(ledgerHash(ledger).toHex()).toBe(ledger.hash)
|
||||
})
|
||||
})
|
||||
}
|
||||
testFactory('ledger-full-40000.json')
|
||||
testFactory('ledger-full-38129.json')
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
--reporter spec --slow 500 --require babel-core/register
|
||||
@@ -1,16 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const {quality, binary: {bytesToHex}} = require('../src/coretypes');
|
||||
|
||||
describe('Quality encode/decode', function() {
|
||||
const bookDirectory =
|
||||
'4627DFFCFF8B5A265EDBD8AE8C14A52325DBFEDAF4F5C32E5D06F4C3362FE1D0';
|
||||
const expectedQuality = '195796912.5171664';
|
||||
it('can decode', function() {
|
||||
const decimal = quality.decode(bookDirectory);
|
||||
assert.equal(decimal.toString(), expectedQuality);
|
||||
});
|
||||
it('can encode', function() {
|
||||
const bytes = quality.encode(expectedQuality);
|
||||
assert.equal(bytesToHex(bytes), bookDirectory.slice(-16));
|
||||
});
|
||||
});
|
||||
15
packages/ripple-binary-codec/test/quality.test.js
Normal file
15
packages/ripple-binary-codec/test/quality.test.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const { quality, binary } = require('../dist/coretypes')
|
||||
|
||||
describe('Quality encode/decode', function () {
|
||||
const bookDirectory =
|
||||
'4627DFFCFF8B5A265EDBD8AE8C14A52325DBFEDAF4F5C32E5D06F4C3362FE1D0'
|
||||
const expectedQuality = '195796912.5171664'
|
||||
test('can decode', function () {
|
||||
const decimal = quality.decode(bookDirectory)
|
||||
expect(decimal.toString()).toBe(expectedQuality)
|
||||
})
|
||||
test('can encode', function () {
|
||||
const bytes = quality.encode(expectedQuality)
|
||||
expect(binary.bytesToHex(bytes)).toBe(bookDirectory.slice(-16))
|
||||
})
|
||||
})
|
||||
@@ -1,88 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const {ShaMap} = require('../src/shamap.js');
|
||||
const {binary: {serializeObject}, Hash256, HashPrefix}
|
||||
= require('../src/coretypes');
|
||||
const {loadFixture} = require('./utils');
|
||||
|
||||
function now() {
|
||||
return (Number(Date.now())) / 1000;
|
||||
}
|
||||
|
||||
const ZERO =
|
||||
'0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
function makeItem(indexArg) {
|
||||
let str = indexArg;
|
||||
while (str.length < 64) {
|
||||
str += '0';
|
||||
}
|
||||
const index = Hash256.from(str);
|
||||
const item = {
|
||||
toBytesSink(sink) {
|
||||
index.toBytesSink(sink);
|
||||
},
|
||||
hashPrefix() {
|
||||
return [1, 3, 3, 7];
|
||||
}
|
||||
};
|
||||
return [index, item];
|
||||
}
|
||||
|
||||
describe('ShaMap', () => {
|
||||
now();
|
||||
|
||||
it('hashes to zero when empty', () => {
|
||||
const map = new ShaMap();
|
||||
assert.equal(map.hash().toHex(), ZERO);
|
||||
});
|
||||
it('creates the same hash no matter which order items are added', () => {
|
||||
let map = new ShaMap();
|
||||
const items = [
|
||||
'0',
|
||||
'1',
|
||||
'11',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E20000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E21000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E22000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E23000000000000000',
|
||||
'12',
|
||||
'122'
|
||||
];
|
||||
items.forEach(i => map.addItem(...makeItem(i)));
|
||||
const h1 = map.hash();
|
||||
assert(h1.eq(h1));
|
||||
map = new ShaMap();
|
||||
items.reverse().forEach(i => map.addItem(...makeItem(i)));
|
||||
assert(map.hash().eq(h1));
|
||||
});
|
||||
function factory(fixture) {
|
||||
it(`recreate account state hash from ${fixture}`, () => {
|
||||
const map = new ShaMap();
|
||||
const ledger = loadFixture(fixture);
|
||||
// const t = now();
|
||||
const leafNodePrefix = HashPrefix.accountStateEntry;
|
||||
ledger.accountState.map((e, i) => {
|
||||
if (i > 1000 & (i % 1000) === 0) {
|
||||
console.log(e.index);
|
||||
console.log(i);
|
||||
}
|
||||
const bytes = serializeObject(e);
|
||||
return {
|
||||
index: Hash256.from(e.index),
|
||||
hashPrefix() {
|
||||
return leafNodePrefix;
|
||||
},
|
||||
toBytesSink(sink) {
|
||||
sink.put(bytes);
|
||||
}
|
||||
};
|
||||
}).forEach(so => map.addItem(so.index, so));
|
||||
assert.equal(map.hash().toHex(), ledger.account_hash);
|
||||
// console.log('took seconds: ', (now() - t));
|
||||
});
|
||||
}
|
||||
factory('ledger-full-38129.json');
|
||||
factory('ledger-full-40000.json');
|
||||
// factory('ledger-4320277.json');
|
||||
// factory('14280680.json');
|
||||
});
|
||||
87
packages/ripple-binary-codec/test/shamap.test.js
Normal file
87
packages/ripple-binary-codec/test/shamap.test.js
Normal file
@@ -0,0 +1,87 @@
|
||||
const { ShaMap } = require('../dist/shamap.js')
|
||||
const { binary, HashPrefix } = require('../dist/coretypes')
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { loadFixture } = require('./utils')
|
||||
|
||||
function now () {
|
||||
return (Number(Date.now())) / 1000
|
||||
}
|
||||
|
||||
const ZERO =
|
||||
'0000000000000000000000000000000000000000000000000000000000000000'
|
||||
|
||||
function makeItem (indexArg) {
|
||||
let str = indexArg
|
||||
while (str.length < 64) {
|
||||
str += '0'
|
||||
}
|
||||
const index = coreTypes.Hash256.from(str)
|
||||
const item = {
|
||||
toBytesSink (sink) {
|
||||
index.toBytesSink(sink)
|
||||
},
|
||||
hashPrefix () {
|
||||
return [1, 3, 3, 7]
|
||||
}
|
||||
}
|
||||
return [index, item]
|
||||
}
|
||||
|
||||
describe('ShaMap', () => {
|
||||
now()
|
||||
|
||||
test('hashes to zero when empty', () => {
|
||||
const map = new ShaMap()
|
||||
expect(map.hash().toHex()).toBe(ZERO)
|
||||
})
|
||||
test('creates the same hash no matter which order items are added', () => {
|
||||
let map = new ShaMap()
|
||||
const items = [
|
||||
'0',
|
||||
'1',
|
||||
'11',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E20000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E21000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E22000000000000000',
|
||||
'7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E23000000000000000',
|
||||
'12',
|
||||
'122'
|
||||
]
|
||||
items.forEach(i => map.addItem(...makeItem(i)))
|
||||
const h1 = map.hash()
|
||||
expect(h1.eq(h1)).toBe(true)
|
||||
map = new ShaMap()
|
||||
items.reverse().forEach(i => map.addItem(...makeItem(i)))
|
||||
expect(map.hash()).toStrictEqual(h1)
|
||||
})
|
||||
function factory (fixture) {
|
||||
test(`recreate account state hash from ${fixture}`, () => {
|
||||
const map = new ShaMap()
|
||||
const ledger = loadFixture(fixture)
|
||||
// const t = now();
|
||||
const leafNodePrefix = HashPrefix.accountStateEntry
|
||||
ledger.accountState.map((e, i) => {
|
||||
if (i > 1000 & (i % 1000) === 0) {
|
||||
console.log(e.index)
|
||||
console.log(i)
|
||||
}
|
||||
const bytes = binary.serializeObject(e)
|
||||
return {
|
||||
index: coreTypes.Hash256.from(e.index),
|
||||
hashPrefix () {
|
||||
return leafNodePrefix
|
||||
},
|
||||
toBytesSink (sink) {
|
||||
sink.put(bytes)
|
||||
}
|
||||
}
|
||||
}).forEach(so => map.addItem(so.index, so))
|
||||
expect(map.hash().toHex()).toBe(ledger.account_hash)
|
||||
// console.log('took seconds: ', (now() - t));
|
||||
})
|
||||
}
|
||||
factory('ledger-full-38129.json')
|
||||
factory('ledger-full-40000.json')
|
||||
// factory('ledger-4320277.json');
|
||||
// factory('14280680.json');
|
||||
})
|
||||
@@ -1,7 +1,5 @@
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const {encodeForSigning, encodeForSigningClaim, encodeForMultisigning} =
|
||||
require('../src');
|
||||
const _ = require('lodash')
|
||||
const { encodeForSigning, encodeForSigningClaim, encodeForMultisigning } = require('../dist')
|
||||
|
||||
const tx_json = {
|
||||
Account: 'r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ',
|
||||
@@ -19,12 +17,12 @@ const tx_json = {
|
||||
'3CD7B9B',
|
||||
SigningPubKey:
|
||||
'ED5F5AC8B98974A3CA843326D9B88CEBD0560177B973EE0B149F782CFAA06DC66A'
|
||||
};
|
||||
}
|
||||
|
||||
describe('Signing data', function() {
|
||||
it('can create single signing blobs', function() {
|
||||
const actual = encodeForSigning(tx_json);
|
||||
assert.equal(actual,
|
||||
describe('Signing data', function () {
|
||||
test('can create single signing blobs', function () {
|
||||
const actual = encodeForSigning(tx_json)
|
||||
expect(actual).toBe(
|
||||
['53545800', // signingPrefix
|
||||
// TransactionType
|
||||
'12',
|
||||
@@ -58,13 +56,13 @@ describe('Signing data', function() {
|
||||
// VLLength
|
||||
'14',
|
||||
'B5F762798A53D543A014CAF8B297CFF8F2F937E8'].join('')
|
||||
);
|
||||
});
|
||||
it('can create multi signing blobs', function() {
|
||||
const signingAccount = 'rJZdUusLDtY9NEsGea7ijqhVrXv98rYBYN';
|
||||
const signingJson = _.assign({}, tx_json, {SigningPubKey: ''});
|
||||
const actual = encodeForMultisigning(signingJson, signingAccount);
|
||||
assert.equal(actual,
|
||||
)
|
||||
})
|
||||
test('can create multi signing blobs', function () {
|
||||
const signingAccount = 'rJZdUusLDtY9NEsGea7ijqhVrXv98rYBYN'
|
||||
const signingJson = _.assign({}, tx_json, { SigningPubKey: '' })
|
||||
const actual = encodeForMultisigning(signingJson, signingAccount)
|
||||
expect(actual).toBe(
|
||||
['534D5400', // signingPrefix
|
||||
// TransactionType
|
||||
'12',
|
||||
@@ -100,15 +98,15 @@ describe('Signing data', function() {
|
||||
'B5F762798A53D543A014CAF8B297CFF8F2F937E8',
|
||||
// signingAccount suffix
|
||||
'C0A5ABEF242802EFED4B041E8F2D4A8CC86AE3D1'].join('')
|
||||
);
|
||||
});
|
||||
it('can create claim blob', function() {
|
||||
)
|
||||
})
|
||||
test('can create claim blob', function () {
|
||||
const channel =
|
||||
'43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1'
|
||||
const amount = '1000'
|
||||
const json = {channel, amount}
|
||||
const json = { channel, amount }
|
||||
const actual = encodeForSigningClaim(json)
|
||||
assert.equal(actual, [
|
||||
expect(actual).toBe([
|
||||
// hash prefix
|
||||
'434C4D00',
|
||||
// channel ID
|
||||
@@ -117,4 +115,4 @@ describe('Signing data', function() {
|
||||
'00000000000003E8'
|
||||
].join(''))
|
||||
})
|
||||
});
|
||||
})
|
||||
@@ -1,8 +1,7 @@
|
||||
const assert = require('assert');
|
||||
const {
|
||||
encode,
|
||||
decode
|
||||
} = require('../src')
|
||||
} = require('../dist')
|
||||
|
||||
// Notice: no Amount or Fee
|
||||
const tx_json = {
|
||||
@@ -20,7 +19,7 @@ const tx_json = {
|
||||
// TxnSignature,
|
||||
// Signature,
|
||||
// SigningPubKey
|
||||
};
|
||||
}
|
||||
|
||||
const amount_parameters_message = input => {
|
||||
// disables the ESLint rule on the whole rest of the file
|
||||
@@ -41,84 +40,82 @@ Thus the largest serializable IOU value is:
|
||||
|
||||
And the smallest:
|
||||
0.000000000000000000000000000000000000000000000000000000000000000000000000000000001
|
||||
`;
|
||||
};
|
||||
`
|
||||
}
|
||||
|
||||
describe('encoding and decoding tx_json', function() {
|
||||
it('can encode tx_json without Amount or Fee', function() {
|
||||
const encoded = encode(tx_json);
|
||||
const decoded = decode(encoded);
|
||||
assert.deepStrictEqual(tx_json, decoded);
|
||||
});
|
||||
it('can encode tx_json with Amount and Fee', function() {
|
||||
describe('encoding and decoding tx_json', function () {
|
||||
test('can encode tx_json without Amount or Fee', function () {
|
||||
const encoded = encode(tx_json)
|
||||
const decoded = decode(encoded)
|
||||
expect(tx_json).toEqual(decoded)
|
||||
})
|
||||
test('can encode tx_json with Amount and Fee', function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: '1000',
|
||||
Fee: '10'
|
||||
});
|
||||
const encoded = encode(my_tx);
|
||||
const decoded = decode(encoded);
|
||||
assert.deepStrictEqual(my_tx, decoded);
|
||||
});
|
||||
it('throws when Amount is invalid', function() {
|
||||
})
|
||||
const encoded = encode(my_tx)
|
||||
const decoded = decode(encoded)
|
||||
expect(my_tx).toEqual(decoded)
|
||||
})
|
||||
test('throws when Amount is invalid', function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: '1000.001',
|
||||
Fee: '10'
|
||||
});
|
||||
assert.throws(() => {
|
||||
encode(my_tx);
|
||||
}, {
|
||||
})
|
||||
expect(() => {
|
||||
encode(my_tx)
|
||||
}).toThrow({
|
||||
name: 'Error',
|
||||
message: amount_parameters_message('1000.001')
|
||||
});
|
||||
});
|
||||
it('throws when Fee is invalid', function() {
|
||||
})
|
||||
})
|
||||
test('throws when Fee is invalid', function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: '1000',
|
||||
Fee: '10.123'
|
||||
});
|
||||
assert.throws(() => {
|
||||
encode(my_tx);
|
||||
}, {
|
||||
})
|
||||
expect(() => {
|
||||
encode(my_tx)
|
||||
}).toThrow({
|
||||
name: 'Error',
|
||||
message: amount_parameters_message('10.123')
|
||||
});
|
||||
});
|
||||
it('throws when Amount and Fee are invalid', function() {
|
||||
})
|
||||
})
|
||||
test('throws when Amount and Fee are invalid', function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: '1000.789',
|
||||
Fee: '10.123'
|
||||
});
|
||||
assert.throws(() => {
|
||||
encode(my_tx);
|
||||
}, {
|
||||
})
|
||||
expect(() => {
|
||||
encode(my_tx)
|
||||
}).toThrow({
|
||||
name: 'Error',
|
||||
message: amount_parameters_message('1000.789')
|
||||
});
|
||||
});
|
||||
it('throws when Amount is a number instead of a string-encoded integer',
|
||||
function() {
|
||||
})
|
||||
})
|
||||
test('throws when Amount is a number instead of a string-encoded integer',
|
||||
function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: 1000.789
|
||||
});
|
||||
assert.throws(() => {
|
||||
encode(my_tx);
|
||||
},
|
||||
{
|
||||
})
|
||||
expect(() => {
|
||||
encode(my_tx)
|
||||
}).toThrow({
|
||||
name: 'Error',
|
||||
message: 'unsupported value: 1000.789'
|
||||
});
|
||||
});
|
||||
it('throws when Fee is a number instead of a string-encoded integer',
|
||||
function() {
|
||||
})
|
||||
})
|
||||
test('throws when Fee is a number instead of a string-encoded integer',
|
||||
function () {
|
||||
const my_tx = Object.assign({}, tx_json, {
|
||||
Amount: 1234.56
|
||||
});
|
||||
assert.throws(() => {
|
||||
encode(my_tx);
|
||||
},
|
||||
{
|
||||
})
|
||||
expect(() => {
|
||||
encode(my_tx)
|
||||
}).toThrow({
|
||||
name: 'Error',
|
||||
message: 'unsupported value: 1234.56'
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,38 +0,0 @@
|
||||
const _ = require('lodash');
|
||||
const assert = require('assert');
|
||||
const coreTypes = require('../src/types');
|
||||
const {SerializedType} = require('../src/types/serialized-type');
|
||||
|
||||
describe('SerializedType interfaces', () => {
|
||||
_.forOwn(coreTypes, (Value, name) => {
|
||||
it(`${name} has a \`from\` static constructor`, () => {
|
||||
assert(Value.from && Value.from !== Array.from);
|
||||
});
|
||||
it(`${name} has a default constructor`, () => {
|
||||
/* eslint-disable no-new*/
|
||||
new Value();
|
||||
/* eslint-enable no-new*/
|
||||
});
|
||||
it(`${name}.from will return the same object`, () => {
|
||||
const instance = new Value();
|
||||
assert(Value.from(instance) === instance);
|
||||
});
|
||||
it(`${name} instances have toBytesSink`, () => {
|
||||
assert(new Value().toBytesSink);
|
||||
});
|
||||
it(`${name} instances have toJSON`, () => {
|
||||
assert(new Value().toJSON);
|
||||
});
|
||||
it(`${name}.from(json).toJSON() == json`, () => {
|
||||
const newJSON = new Value().toJSON();
|
||||
assert.deepEqual(Value.from(newJSON).toJSON(), newJSON);
|
||||
});
|
||||
describe(`${name} supports all methods of the SerializedType mixin`, () => {
|
||||
_.keys(SerializedType).forEach(k => {
|
||||
it(`new ${name}.prototype.${k} !== undefined`, () => {
|
||||
assert.notEqual(Value.prototype[k], undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
37
packages/ripple-binary-codec/test/types.test.js
Normal file
37
packages/ripple-binary-codec/test/types.test.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const _ = require('lodash')
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { SerializedType } = require('../dist/types/serialized-type')
|
||||
|
||||
describe('SerializedType interfaces', () => {
|
||||
_.forOwn(coreTypes, (Value, name) => {
|
||||
test(`${name} has a \`from\` static constructor`, () => {
|
||||
expect(Value.from && Value.from !== Array.from).toBe(true)
|
||||
})
|
||||
test(`${name} has a default constructor`, () => {
|
||||
/* eslint-disable no-new */
|
||||
new Value()
|
||||
/* eslint-enable no-new */
|
||||
})
|
||||
test(`${name}.from will return the same object`, () => {
|
||||
const instance = new Value()
|
||||
expect(Value.from(instance) === instance).toBe(true)
|
||||
})
|
||||
test(`${name} instances have toBytesSink`, () => {
|
||||
expect(new Value().toBytesSink).not.toBe(undefined)
|
||||
})
|
||||
test(`${name} instances have toJSON`, () => {
|
||||
expect(new Value().toJSON).not.toBe(undefined)
|
||||
})
|
||||
test(`${name}.from(json).toJSON() == json`, () => {
|
||||
const newJSON = new Value().toJSON()
|
||||
expect(Value.from(newJSON).toJSON()).toEqual(newJSON)
|
||||
})
|
||||
describe(`${name} supports all methods of the SerializedType mixin`, () => {
|
||||
_.keys(SerializedType).forEach(k => {
|
||||
test(`new ${name}.prototype.${k} !== undefined`, () => {
|
||||
expect(Value.prototype[k]).not.toBe(undefined)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,38 +0,0 @@
|
||||
const assert = require('assert');
|
||||
const coreTypes = require('../src/coretypes');
|
||||
/* eslint-disable no-unused-vars */
|
||||
const {UInt8, UInt16, UInt32, UInt64} = coreTypes;
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
function compareToTests() {
|
||||
|
||||
function check(expr, is) {
|
||||
it(expr, function() {
|
||||
/* eslint-disable no-eval */
|
||||
assert.equal(eval(expr), is);
|
||||
/* eslint-enable no-eval */
|
||||
});
|
||||
}
|
||||
check('UInt8.from(124).compareTo(UInt64.from(124))', 0);
|
||||
check('UInt64.from(124).compareTo(UInt8.from(124))', 0);
|
||||
check('UInt64.from(124).compareTo(UInt8.from(123))', 1);
|
||||
check('UInt8.from(124).compareTo(UInt8.from(13))', 1);
|
||||
check('UInt8.from(124).compareTo(124)', 0);
|
||||
check('UInt64.from(124).compareTo(124)', 0);
|
||||
check('UInt64.from(124).compareTo(123)', 1);
|
||||
check('UInt8.from(124).compareTo(13)', 1);
|
||||
}
|
||||
|
||||
function valueOfTests() {
|
||||
it('The Uint classes work with |= operator', function() {
|
||||
let val = UInt8.from(1);
|
||||
val |= 0x2;
|
||||
assert.equal(val, 3);
|
||||
});
|
||||
}
|
||||
|
||||
describe('Uint*', function() {
|
||||
describe('compareToTests', compareToTests);
|
||||
describe('valueOfTests', valueOfTests);
|
||||
});
|
||||
|
||||
40
packages/ripple-binary-codec/test/uint.test.js
Normal file
40
packages/ripple-binary-codec/test/uint.test.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { coreTypes } = require('../dist/types')
|
||||
const { UInt8, UInt64 } = coreTypes
|
||||
|
||||
test('compareToTests', () => {
|
||||
expect(UInt8.from(124).compareTo(UInt64.from(124))).toBe(-0)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt64.from(124).compareTo(UInt8.from(124))).toBe(0)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt64.from(124).compareTo(UInt8.from(123))).toBe(1)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt8.from(124).compareTo(UInt8.from(13))).toBe(1)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt8.from(124).compareTo(124)).toBe(0)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt64.from(124).compareTo(124)).toBe(0)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt64.from(124).compareTo(123)).toBe(1)
|
||||
})
|
||||
|
||||
test('compareToTest', () => {
|
||||
expect(UInt8.from(124).compareTo(13)).toBe(1)
|
||||
})
|
||||
|
||||
test('valueOfTests', () => {
|
||||
let val = UInt8.from(1)
|
||||
val |= 0x2
|
||||
expect(val).toBe(3)
|
||||
})
|
||||
@@ -1,83 +1,24 @@
|
||||
const intercept = require('intercept-stdout');
|
||||
const fs = require('fs');
|
||||
const fsExtra = require('fs-extra');
|
||||
const assert = require('assert');
|
||||
const Decimal = require('decimal.js');
|
||||
const {parseBytes} = require('../src/utils/bytes-utils');
|
||||
const fs = require('fs')
|
||||
const { parseBytes } = require('../dist/utils/bytes-utils')
|
||||
|
||||
function hexOnly(hex) {
|
||||
return hex.replace(/[^a-fA-F0-9]/g, '');
|
||||
function hexOnly (hex) {
|
||||
return hex.replace(/[^a-fA-F0-9]/g, '')
|
||||
}
|
||||
|
||||
function unused() {}
|
||||
function unused () {}
|
||||
|
||||
function captureLogsAsync() {
|
||||
let log = '';
|
||||
const unhook = intercept(txt => {
|
||||
log += txt;
|
||||
return '';
|
||||
});
|
||||
return function() {
|
||||
unhook();
|
||||
return log;
|
||||
};
|
||||
function parseHexOnly (hex, to) {
|
||||
return parseBytes(hexOnly(hex), to)
|
||||
}
|
||||
|
||||
function captureLogs(func) {
|
||||
const finished = captureLogsAsync();
|
||||
try {
|
||||
func();
|
||||
} catch (e) {
|
||||
const log = finished();
|
||||
console.error(log);
|
||||
throw e;
|
||||
}
|
||||
return finished();
|
||||
function loadFixture (relativePath) {
|
||||
const fn = __dirname + '/fixtures/' + relativePath
|
||||
return require(fn)
|
||||
}
|
||||
|
||||
function parseHexOnly(hex, to) {
|
||||
return parseBytes(hexOnly(hex), to);
|
||||
}
|
||||
|
||||
function loadFixture(relativePath) {
|
||||
const fn = __dirname + '/fixtures/' + relativePath;
|
||||
return require(fn);
|
||||
}
|
||||
|
||||
function isBufferOrString(val) {
|
||||
return Buffer.isBuffer(val) || (typeof val === 'string');
|
||||
}
|
||||
|
||||
function loadFixtureText(relativePath) {
|
||||
const fn = __dirname + '/fixtures/' + relativePath;
|
||||
return fs.readFileSync(fn).toString('utf8');
|
||||
}
|
||||
|
||||
function fixturePath(relativePath) {
|
||||
return __dirname + '/fixtures/' + relativePath;
|
||||
}
|
||||
|
||||
function prettyJSON(val) {
|
||||
return JSON.stringify(val, null, 2);
|
||||
}
|
||||
|
||||
function writeFixture(relativePath, data) {
|
||||
const out = isBufferOrString(data) ? data : prettyJSON(data);
|
||||
return fsExtra.outputFileSync(fixturePath(relativePath), out);
|
||||
}
|
||||
|
||||
function assertEqualAmountJSON(actual, expected) {
|
||||
const typeA = (typeof actual);
|
||||
assert(typeA === (typeof expected));
|
||||
if (typeA === 'string') {
|
||||
assert.equal(actual, expected);
|
||||
return;
|
||||
}
|
||||
assert.equal(actual.currency, expected.currency);
|
||||
assert.equal(actual.issuer, expected.issuer);
|
||||
assert(actual.value === expected.value ||
|
||||
new Decimal(actual.value).equals(
|
||||
new Decimal(expected.value)));
|
||||
function loadFixtureText (relativePath) {
|
||||
const fn = __dirname + '/fixtures/' + relativePath
|
||||
return fs.readFileSync(fn).toString('utf8')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -85,9 +26,5 @@ module.exports = {
|
||||
parseHexOnly,
|
||||
loadFixture,
|
||||
loadFixtureText,
|
||||
assertEqualAmountJSON,
|
||||
writeFixture,
|
||||
unused,
|
||||
captureLogs,
|
||||
captureLogsAsync
|
||||
};
|
||||
unused
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user