- Add GETTING_STARTED.md with quick start guide and development modes - Add INSTALL.sh automated installation script - Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md - Add QUICK_REFERENCE.md for common commands - Add SETUP_GUIDE.md with detailed setup instructions - Update README.md with improved project overview - Add did-wallet app dependencies and node_modules
668 lines
14 KiB
JavaScript
668 lines
14 KiB
JavaScript
'use strict';
|
|
|
|
var chai = require('chai');
|
|
require('../cborg.js');
|
|
var byteUtils = require('../lib/byte-utils.js');
|
|
var decode = require('../lib/decode.js');
|
|
var encode = require('../lib/encode.js');
|
|
|
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
|
|
var chai__default = /*#__PURE__*/_interopDefaultLegacy(chai);
|
|
|
|
const {assert} = chai__default["default"];
|
|
const fixtures = [
|
|
{
|
|
data: 'a0',
|
|
expected: {},
|
|
type: 'map empty'
|
|
},
|
|
{
|
|
data: 'a0',
|
|
expected: new Map(),
|
|
type: 'map empty (useMaps)',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'a1616101',
|
|
expected: { a: 1 },
|
|
type: 'map 1 pair'
|
|
},
|
|
{
|
|
data: 'a161316161',
|
|
expected: { 1: 'a' },
|
|
type: 'map 1 pair (rev)'
|
|
},
|
|
{
|
|
data: 'a1016161',
|
|
expected: toMap([[
|
|
1,
|
|
'a'
|
|
]]),
|
|
type: 'map 1 pair (int key as Map w/ useMaps)',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'a243010203633132334302030463323334',
|
|
expected: toMap([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
3
|
|
]),
|
|
'123'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
3,
|
|
4
|
|
]),
|
|
'234'
|
|
]
|
|
]),
|
|
type: 'map 2 pair (bytes keys Map w/ useMaps)',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'a1666f626a656374a16477697468a26134666e6573746564676f626a65637473a161216121',
|
|
expected: {
|
|
object: {
|
|
with: {
|
|
4: 'nested',
|
|
objects: { '!': '!' }
|
|
}
|
|
}
|
|
},
|
|
type: 'map nested'
|
|
},
|
|
{
|
|
data: 'a1666f626a656374a16477697468a204666e6573746564676f626a65637473a161216121',
|
|
expected: toMap([[
|
|
'object',
|
|
toMap([[
|
|
'with',
|
|
toMap([
|
|
[
|
|
4,
|
|
'nested'
|
|
],
|
|
[
|
|
'objects',
|
|
toMap([[
|
|
'!',
|
|
'!'
|
|
]])
|
|
]
|
|
])
|
|
]])
|
|
]]),
|
|
type: 'map nested w/ useMaps',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'ae636f6e651b0016db6db6db6db763736978206374656e3b0016db6db6db6db76374776f1a0001000064666976650064666f757202646e696e653aa5f702b365656967687438ff65736576656e226574687265651901f466656c6576656e426131667477656c76656fc48c6175657320c39f76c49b74652168666f75727465656ea4616664666f7572616f016174026274680368746869727465656e840203046466697665',
|
|
encode: {
|
|
one: Number.MAX_SAFE_INTEGER / 1.4,
|
|
two: 65536,
|
|
three: 500,
|
|
four: 2,
|
|
five: 0,
|
|
six: -1,
|
|
seven: -3,
|
|
eight: -256,
|
|
nine: -2784428724,
|
|
ten: Number.MIN_SAFE_INTEGER / 1.4 - 1,
|
|
eleven: new TextEncoder().encode('a1'),
|
|
twelve: 'Čaues ßvěte!',
|
|
thirteen: [
|
|
2,
|
|
3,
|
|
4,
|
|
'five'
|
|
],
|
|
fourteen: {
|
|
o: 1,
|
|
t: 2,
|
|
th: 3,
|
|
f: 'four'
|
|
}
|
|
},
|
|
expected: {
|
|
one: Number.MAX_SAFE_INTEGER / 1.4,
|
|
six: -1,
|
|
ten: Number.MIN_SAFE_INTEGER / 1.4 - 1,
|
|
two: 65536,
|
|
five: 0,
|
|
four: 2,
|
|
nine: -2784428724,
|
|
eight: -256,
|
|
seven: -3,
|
|
three: 500,
|
|
eleven: new TextEncoder().encode('a1'),
|
|
twelve: 'Čaues ßvěte!',
|
|
fourteen: {
|
|
f: 'four',
|
|
o: 1,
|
|
t: 2,
|
|
th: 3
|
|
},
|
|
thirteen: [
|
|
2,
|
|
3,
|
|
4,
|
|
'five'
|
|
]
|
|
},
|
|
type: 'map with complex entries',
|
|
label: '{}'
|
|
},
|
|
{
|
|
data: 'ad01636f6e65026374776f1901f46c666976652068756e647265641902586b7369782068756e647265641a00010000636269671b0016db6db6db6db76662696767657220696d696e7573206f6e6521696d696e75732074776f38ff781f6d696e75732074776f2068756e6472656420616e64206669667479207369783901f4781a6d696e757820666976652068756e6472656420616e64206f6e653901f5781a6d696e757820666976652068756e6472656420616e642074776f3aa5f702b367626967206e65673b0016db6db6db6db76a626967676572206e6567',
|
|
encode: toMap([
|
|
[
|
|
2,
|
|
'two'
|
|
],
|
|
[
|
|
1,
|
|
'one'
|
|
],
|
|
[
|
|
-2,
|
|
'minus two'
|
|
],
|
|
[
|
|
-1,
|
|
'minus one'
|
|
],
|
|
[
|
|
600,
|
|
'six hundred'
|
|
],
|
|
[
|
|
500,
|
|
'five hundred'
|
|
],
|
|
[
|
|
-256,
|
|
'minus two hundred and fifty six'
|
|
],
|
|
[
|
|
-502,
|
|
'minux five hundred and two'
|
|
],
|
|
[
|
|
-501,
|
|
'minux five hundred and one'
|
|
],
|
|
[
|
|
65536,
|
|
'big'
|
|
],
|
|
[
|
|
-2784428724,
|
|
'big neg'
|
|
],
|
|
[
|
|
6433713753386423,
|
|
'bigger'
|
|
],
|
|
[
|
|
-6433713753386424,
|
|
'bigger neg'
|
|
]
|
|
]),
|
|
expected: toMap([
|
|
[
|
|
1,
|
|
'one'
|
|
],
|
|
[
|
|
2,
|
|
'two'
|
|
],
|
|
[
|
|
500,
|
|
'five hundred'
|
|
],
|
|
[
|
|
600,
|
|
'six hundred'
|
|
],
|
|
[
|
|
65536,
|
|
'big'
|
|
],
|
|
[
|
|
6433713753386423,
|
|
'bigger'
|
|
],
|
|
[
|
|
-1,
|
|
'minus one'
|
|
],
|
|
[
|
|
-2,
|
|
'minus two'
|
|
],
|
|
[
|
|
-256,
|
|
'minus two hundred and fifty six'
|
|
],
|
|
[
|
|
-501,
|
|
'minux five hundred and one'
|
|
],
|
|
[
|
|
-502,
|
|
'minux five hundred and two'
|
|
],
|
|
[
|
|
-2784428724,
|
|
'big neg'
|
|
],
|
|
[
|
|
-6433713753386424,
|
|
'bigger neg'
|
|
]
|
|
]),
|
|
type: 'map with ints and negints',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'a44104636f6e65430102026374776f430102036574687265654301020464666f7572',
|
|
encode: toMap([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
3
|
|
]),
|
|
'three'
|
|
],
|
|
[
|
|
Uint8Array.from([4]),
|
|
'one'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
4
|
|
]),
|
|
'four'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
2
|
|
]),
|
|
'two'
|
|
]
|
|
]),
|
|
expected: toMap([
|
|
[
|
|
Uint8Array.from([4]),
|
|
'one'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
2
|
|
]),
|
|
'two'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
3
|
|
]),
|
|
'three'
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2,
|
|
4
|
|
]),
|
|
'four'
|
|
]
|
|
]),
|
|
type: 'map with bytes keys',
|
|
useMaps: true
|
|
},
|
|
{
|
|
data: 'b801616101',
|
|
expected: { a: 1 },
|
|
type: 'map 1 pair, length8',
|
|
strict: false
|
|
},
|
|
{
|
|
data: 'b90001616101',
|
|
expected: { a: 1 },
|
|
type: 'map 1 pair, length16',
|
|
strict: false
|
|
},
|
|
{
|
|
data: 'ba00000001616101',
|
|
expected: { a: 1 },
|
|
type: 'map 1 pair, length32',
|
|
strict: false
|
|
},
|
|
{
|
|
data: 'bb0000000000000001616101',
|
|
expected: { a: 1 },
|
|
type: 'map 1 pair, length64',
|
|
strict: false
|
|
}
|
|
];
|
|
function toMap(arr) {
|
|
const m = new Map();
|
|
for (const [key, value] of arr) {
|
|
m.set(key, value);
|
|
}
|
|
return m;
|
|
}
|
|
function entries(map) {
|
|
function nest(a) {
|
|
for (const e of a) {
|
|
e[0] = entries(e[0]);
|
|
e[1] = entries(e[1]);
|
|
}
|
|
return a;
|
|
}
|
|
if (Object.getPrototypeOf(map) === Map.prototype) {
|
|
return nest([...map.entries()]);
|
|
}
|
|
if (typeof map === 'object') {
|
|
return nest([...Object.entries(map)]);
|
|
}
|
|
return map;
|
|
}
|
|
describe('map', () => {
|
|
describe('decode', () => {
|
|
for (const fixture of fixtures) {
|
|
const data = byteUtils.fromHex(fixture.data);
|
|
it(`should decode ${ fixture.type }=${ fixture.label || JSON.stringify(fixture.expected) }`, () => {
|
|
let options = fixture.useMaps ? { useMaps: true } : undefined;
|
|
const decoded = decode.decode(data, options);
|
|
if (fixture.useMaps) {
|
|
assert.strictEqual(Object.getPrototypeOf(decoded), Map.prototype, 'is Map');
|
|
} else {
|
|
assert.isObject(decoded, 'is object');
|
|
}
|
|
assert.deepStrictEqual(entries(decoded), entries(fixture.expected), `decode ${ fixture.type }`);
|
|
options = Object.assign({ strict: true }, options);
|
|
if (fixture.strict === false) {
|
|
assert.throws(() => decode.decode(data, options), Error, 'CBOR decode error: integer encoded in more bytes than necessary (strict decode)');
|
|
} else {
|
|
assert.deepStrictEqual(entries(decode.decode(data, options)), entries(fixture.expected), `decode ${ fixture.type }`);
|
|
}
|
|
});
|
|
it('should fail to decode very large length', () => {
|
|
assert.throws(() => decode.decode(byteUtils.fromHex('bba5f702b3a5f70201616101')), /CBOR decode error: 64-bit integer map lengths not supported/);
|
|
});
|
|
}
|
|
it('errors', () => {
|
|
assert.throws(() => decode.decode(byteUtils.fromHex('a1016161')), /non-string keys not supported \(got number\)/);
|
|
});
|
|
});
|
|
describe('encode', () => {
|
|
for (const fixture of fixtures) {
|
|
it(`should encode ${ fixture.type }=${ fixture.label || JSON.stringify(fixture.expected) }`, () => {
|
|
const toEncode = fixture.encode || fixture.expected;
|
|
if (fixture.unsafe) {
|
|
assert.throws(encode.encode.bind(null, toEncode), Error, /^CBOR encode error: number too large to encode \(\d+\)$/);
|
|
} else if (fixture.strict === false || fixture.roundtrip === false) {
|
|
assert.notDeepEqual(byteUtils.toHex(encode.encode(toEncode)), fixture.data, `encode ${ fixture.type } !strict`);
|
|
} else {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(toEncode)), fixture.data, `encode ${ fixture.type }`);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
describe('roundtrip', () => {
|
|
for (const fixture of fixtures) {
|
|
if (!fixture.unsafe && fixture.strict !== false && fixture.roundtrip !== false) {
|
|
it(`should roundtrip ${ fixture.type }=${ fixture.label || JSON.stringify(fixture.expected) }`, () => {
|
|
const toEncode = fixture.encode || fixture.expected;
|
|
const options = fixture.useMaps ? { useMaps: true } : undefined;
|
|
const rt = decode.decode(encode.encode(toEncode), options);
|
|
if (fixture.useMaps) {
|
|
assert.strictEqual(Object.getPrototypeOf(rt), Map.prototype, 'is Map');
|
|
} else {
|
|
assert.isObject(rt, 'is object');
|
|
}
|
|
assert.deepStrictEqual(entries(rt), entries(fixture.expected), `roundtrip ${ fixture.type }`);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
describe('specials', () => {
|
|
it('can decode indefinite length items', () => {
|
|
assert.deepStrictEqual(decode.decode(byteUtils.fromHex('bf616f01617402ff')), {
|
|
o: 1,
|
|
t: 2
|
|
});
|
|
});
|
|
it('can switch off indefinite length support', () => {
|
|
assert.throws(() => decode.decode(byteUtils.fromHex('bf616f01617402ff'), { allowIndefinite: false }), /indefinite/);
|
|
});
|
|
});
|
|
describe('sorting', () => {
|
|
it('sorts int map keys', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
1,
|
|
1
|
|
],
|
|
[
|
|
2,
|
|
2
|
|
]
|
|
]))), 'a201010202');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
2,
|
|
1
|
|
],
|
|
[
|
|
1,
|
|
2
|
|
]
|
|
]))), 'a201020201');
|
|
});
|
|
it('sorts negint map keys', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
-1,
|
|
1
|
|
],
|
|
[
|
|
-2,
|
|
2
|
|
]
|
|
]))), 'a220012102');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
-2,
|
|
1
|
|
],
|
|
[
|
|
-1,
|
|
2
|
|
]
|
|
]))), 'a220022101');
|
|
});
|
|
it('sorts bytes map keys', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
2
|
|
]
|
|
]))), 'a24201020142020102');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
2
|
|
]
|
|
]))), 'a24201020242020101');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
2
|
|
],
|
|
[
|
|
Uint8Array.from([200]),
|
|
3
|
|
]
|
|
]))), 'a341c8034201020142020102');
|
|
});
|
|
it('sorts bytes map keys', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
2
|
|
]
|
|
]))), 'a24201020142020102');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
2
|
|
]
|
|
]))), 'a24201020242020101');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
Uint8Array.from([
|
|
1,
|
|
2
|
|
]),
|
|
1
|
|
],
|
|
[
|
|
Uint8Array.from([
|
|
2,
|
|
1
|
|
]),
|
|
2
|
|
],
|
|
[
|
|
Uint8Array.from([200]),
|
|
3
|
|
]
|
|
]))), 'a341c8034201020142020102');
|
|
});
|
|
it('sorts array map keys (length only)', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
[1],
|
|
1
|
|
],
|
|
[
|
|
[
|
|
1,
|
|
1
|
|
],
|
|
2
|
|
]
|
|
]))), 'a281010182010102');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
[
|
|
1,
|
|
1
|
|
],
|
|
1
|
|
],
|
|
[
|
|
[1],
|
|
2
|
|
]
|
|
]))), 'a281010282010101');
|
|
});
|
|
it('sorts map map keys (length only)', () => {
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
{ a: 1 },
|
|
1
|
|
],
|
|
[
|
|
{
|
|
a: 1,
|
|
b: 1
|
|
},
|
|
2
|
|
]
|
|
]))), 'a2a161610101a261610161620102');
|
|
assert.strictEqual(byteUtils.toHex(encode.encode(new Map([
|
|
[
|
|
{
|
|
a: 1,
|
|
b: 1
|
|
},
|
|
1
|
|
],
|
|
[
|
|
{ a: 1 },
|
|
2
|
|
]
|
|
]))), 'a2a161610102a261610161620101');
|
|
});
|
|
});
|
|
});
|