Move test files to correct packages (#4345)
* Move test files to correct packages * Adjust
This commit is contained in:
@@ -1,191 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { I32, Text, U32 } from '../primitive';
|
||||
import { Constructor } from '../types';
|
||||
import { ITuple } from '../types/interfaces';
|
||||
import { BTreeMap, Enum, Struct, Tuple } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
class U32TextTuple extends (Tuple.with([U32, Text]) as unknown as Constructor<ITuple<[U32, Text]>>) {}
|
||||
// Reason: We purposefully want `text` to be the first key of the struct and take priority during sorting
|
||||
// eslint-disable-next-line sort-keys
|
||||
class MockStruct extends Struct.with({ text: Text, int: I32 }) {}
|
||||
class MockEnum extends Enum.with({
|
||||
Key1: MockStruct,
|
||||
Key2: MockStruct,
|
||||
Key3: U32TextTuple
|
||||
}) {}
|
||||
|
||||
const mockU32TextMap = new Map<Text, U32>();
|
||||
const mockU32TupleMap = new Map<ITuple<[U32, Text]>, U32>();
|
||||
const mockU32I32Map = new Map<I32, U32>();
|
||||
const mockU32StructMap = new Map<MockStruct, U32>();
|
||||
const mockU32EnumMap = new Map<MockEnum, U32>();
|
||||
|
||||
mockU32TextMap.set(new Text(registry, 'bazzing'), new U32(registry, 69));
|
||||
|
||||
mockU32TupleMap.set((new U32TextTuple(registry, [2, 'ba'])), new U32(registry, 42));
|
||||
mockU32TupleMap.set((new U32TextTuple(registry, [2, 'b'])), new U32(registry, 7));
|
||||
mockU32TupleMap.set((new U32TextTuple(registry, [1, 'baz'])), new U32(registry, 13));
|
||||
|
||||
mockU32I32Map.set(new I32(registry, 255), new U32(registry, 69));
|
||||
mockU32I32Map.set(new I32(registry, -255), new U32(registry, 42));
|
||||
mockU32I32Map.set(new I32(registry, 1000), new U32(registry, 7));
|
||||
mockU32I32Map.set(new I32(registry, -1000), new U32(registry, 25));
|
||||
mockU32I32Map.set(new I32(registry, 0), new U32(registry, 13));
|
||||
|
||||
mockU32StructMap.set(new MockStruct(registry, { int: 1, text: 'b' }), new U32(registry, 42));
|
||||
mockU32StructMap.set(new MockStruct(registry, { int: -1, text: 'b' }), new U32(registry, 7));
|
||||
mockU32StructMap.set(new MockStruct(registry, { int: -1, text: 'ba' }), new U32(registry, 25));
|
||||
mockU32StructMap.set(new MockStruct(registry, { int: -2, text: 'baz' }), new U32(registry, 13));
|
||||
|
||||
mockU32EnumMap.set(new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'ba']) }), new U32(registry, 13));
|
||||
mockU32EnumMap.set(new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'b']) }), new U32(registry, 42));
|
||||
mockU32EnumMap.set(new MockEnum(registry, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 7));
|
||||
mockU32EnumMap.set(new MockEnum(registry, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }), new U32(registry, 25));
|
||||
mockU32EnumMap.set(new MockEnum(registry, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) }), new U32(registry, 69));
|
||||
|
||||
describe('BTreeMap', (): void => {
|
||||
it('decodes null', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeMap.with(Text, U32)
|
||||
)(registry, null).toString()
|
||||
).toEqual('{}');
|
||||
});
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const key = new Text(registry, 'foo');
|
||||
const val = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new (BTreeMap.with(Text, Text))(registry, new Map([[key, val]]))).eq(new Map([[key, val]]))
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('decodes within more complicated types', (): void => {
|
||||
const s = new Struct(registry, {
|
||||
placeholder: U32,
|
||||
value: 'BTreeMap<Text, U32>'
|
||||
});
|
||||
|
||||
s.set('value', new (BTreeMap.with(Text, U32))(registry, mockU32TextMap));
|
||||
expect(s.toString()).toBe('{"placeholder":0,"value":{"bazzing":69}}');
|
||||
});
|
||||
|
||||
it('throws when it cannot decode', (): void => {
|
||||
expect(
|
||||
(): BTreeMap<Text, U32> => new (
|
||||
BTreeMap.with(Text, U32)
|
||||
)(registry, 'ABC')
|
||||
).toThrowError(/Map: cannot decode type/);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeMap.with(Text, U32))(registry, mockU32TextMap).encodedLength
|
||||
).toEqual(13);
|
||||
});
|
||||
|
||||
it('correctly sorts simple keys', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeMap.with(I32, U32))(registry, mockU32I32Map).keys()).map((k) => k.toNumber())
|
||||
).toEqual([-1000, -255, 0, 255, 1000]);
|
||||
});
|
||||
|
||||
it('correctly sorts tuple keys', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeMap.with(U32TextTuple, U32))(registry, mockU32TupleMap).keys()).map((k) => k.toJSON())
|
||||
).toEqual([[1, 'baz'], [2, 'b'], [2, 'ba']]);
|
||||
});
|
||||
|
||||
it('correctly sorts struct keys', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeMap.with(MockStruct, U32))(registry, mockU32StructMap).keys()).map((k) => k.toJSON())
|
||||
).toEqual([
|
||||
{ int: -1, text: 'b' },
|
||||
{ int: 1, text: 'b' },
|
||||
{ int: -1, text: 'ba' },
|
||||
{ int: -2, text: 'baz' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('correctly sorts enum keys', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeMap.with(MockEnum, U32))(registry, mockU32EnumMap).keys()).map((k) => k.toJSON())
|
||||
).toEqual([
|
||||
{ key1: { int: -1, text: 'b' } },
|
||||
{ key1: { int: 1, text: 'b' } },
|
||||
{ key2: { int: -1, text: 'b' } },
|
||||
{ key3: [2, 'b'] },
|
||||
{ key3: [2, 'ba'] }
|
||||
]);
|
||||
});
|
||||
|
||||
it('correctly serializes/deserializes to/from json with numeric keys', (): void => {
|
||||
expect(
|
||||
new (BTreeMap.with(I32, U32))(
|
||||
registry,
|
||||
new (BTreeMap.with(I32, U32))(registry, mockU32I32Map).toJSON()
|
||||
).toJSON()
|
||||
).toEqual({ '-1000': 25, '-255': 42, 0: 13, 1000: 7, 255: 69 });
|
||||
});
|
||||
|
||||
it('correctly serializes/deserializes to/from json with text keys', (): void => {
|
||||
expect(
|
||||
new (BTreeMap.with(Text, U32))(
|
||||
registry,
|
||||
new (BTreeMap.with(Text, U32))(registry, mockU32TextMap).toJSON()
|
||||
).toJSON()
|
||||
).toEqual({ bazzing: 69 });
|
||||
});
|
||||
|
||||
it('correctly serializes/deserializes to/from json with tuple keys', (): void => {
|
||||
expect(
|
||||
new (BTreeMap.with(U32TextTuple, U32))(
|
||||
registry,
|
||||
new (BTreeMap.with(U32TextTuple, U32))(registry, mockU32TupleMap).toJSON()
|
||||
).toJSON()
|
||||
).toEqual({ '[1,"baz"]': 13, '[2,"b"]': 7, '[2,"ba"]': 42 });
|
||||
});
|
||||
|
||||
it('correctly serializes/deserializes to/from json with struct keys', (): void => {
|
||||
expect(
|
||||
new (BTreeMap.with(MockStruct, U32))(
|
||||
registry,
|
||||
new (BTreeMap.with(MockStruct, U32))(registry, mockU32StructMap).toJSON()
|
||||
).toJSON()
|
||||
).toEqual({
|
||||
'{"text":"b","int":-1}': 7,
|
||||
'{"text":"b","int":1}': 42,
|
||||
'{"text":"ba","int":-1}': 25,
|
||||
'{"text":"baz","int":-2}': 13
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly serializes/deserializes to/from json with enum keys', (): void => {
|
||||
expect(
|
||||
new (BTreeMap.with(MockEnum, U32))(
|
||||
registry,
|
||||
new (BTreeMap.with(MockEnum, U32))(registry, mockU32EnumMap).toJSON()
|
||||
).toJSON()
|
||||
).toEqual({
|
||||
'{"key1":{"text":"b","int":-1}}': 69,
|
||||
'{"key1":{"text":"b","int":1}}': 25,
|
||||
'{"key2":{"text":"b","int":-1}}': 7,
|
||||
'{"key3":[2,"b"]}': 42,
|
||||
'{"key3":[2,"ba"]}': 13
|
||||
});
|
||||
});
|
||||
|
||||
it('generates sane toRawTypes', (): void => {
|
||||
expect(new (BTreeMap.with(Text, U32))(registry).toRawType()).toBe('BTreeMap<Text,u32>');
|
||||
expect(new (BTreeMap.with(Text, Text))(registry).toRawType()).toBe('BTreeMap<Text,Text>');
|
||||
expect(new (BTreeMap.with(Text, Struct.with({ a: U32, b: Text })))(registry).toRawType())
|
||||
.toBe('BTreeMap<Text,{"a":"u32","b":"Text"}>');
|
||||
});
|
||||
});
|
||||
@@ -1,184 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { I32, Text, U32 } from '../primitive';
|
||||
import { Constructor } from '../types';
|
||||
import { ITuple } from '../types/interfaces';
|
||||
import { BTreeSet, Enum, Struct, Tuple } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
class U32TextTuple extends (Tuple.with([U32, Text]) as unknown as Constructor<ITuple<[U32, Text]>>) {}
|
||||
// Reason: We purposefully want `text` to be the first key of the struct and take priority during sorting
|
||||
// eslint-disable-next-line sort-keys
|
||||
class MockStruct extends Struct.with({ text: Text, int: I32 }) {}
|
||||
class MockEnum extends Enum.with({
|
||||
Key1: MockStruct,
|
||||
Key2: MockStruct,
|
||||
Key3: U32TextTuple
|
||||
}) {}
|
||||
|
||||
const mockU32Set = new Set<U32>();
|
||||
|
||||
mockU32Set.add(new U32(registry, 2));
|
||||
mockU32Set.add(new U32(registry, 24));
|
||||
mockU32Set.add(new U32(registry, 30));
|
||||
mockU32Set.add(new U32(registry, 80));
|
||||
|
||||
const mockU32SetString = '[2,24,30,80]';
|
||||
const mockU32SetObject = [2, 24, 30, 80];
|
||||
const mockU32SetHexString = '0x1002000000180000001e00000050000000';
|
||||
const mockU32SetUint8Array = Uint8Array.from([16, 2, 0, 0, 0, 24, 0, 0, 0, 30, 0, 0, 0, 80, 0, 0, 0]);
|
||||
|
||||
const mockI32SetObj = [1000, 0, 255, -255, -1000];
|
||||
const mockTextSetObj = [
|
||||
new Text(registry, 'baz'),
|
||||
new Text(registry, 'b'),
|
||||
new Text(registry, 'bb'),
|
||||
new Text(registry, 'ba'),
|
||||
new Text(registry, 'c')
|
||||
];
|
||||
const mockTupleSetObj = [
|
||||
new U32TextTuple(registry, [2, 'ba']),
|
||||
new U32TextTuple(registry, [2, 'bb']),
|
||||
new U32TextTuple(registry, [2, 'b']),
|
||||
new U32TextTuple(registry, [1, 'baz'])
|
||||
];
|
||||
const mockStructSetObj = [
|
||||
new MockStruct(registry, { int: 1, text: 'b' }),
|
||||
new MockStruct(registry, { int: -1, text: 'b' }),
|
||||
new MockStruct(registry, { int: -1, text: 'ba' }),
|
||||
new MockStruct(registry, { int: -2, text: 'baz' })
|
||||
];
|
||||
const mockEnumSetObj = [
|
||||
new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'ba']) }),
|
||||
new MockEnum(registry, { Key3: new U32TextTuple(registry, [2, 'b']) }),
|
||||
new MockEnum(registry, { Key2: new MockStruct(registry, { int: -1, text: 'b' }) }),
|
||||
new MockEnum(registry, { Key1: new MockStruct(registry, { int: 1, text: 'b' }) }),
|
||||
new MockEnum(registry, { Key1: new MockStruct(registry, { int: -1, text: 'b' }) })
|
||||
];
|
||||
|
||||
describe('BTreeSet', (): void => {
|
||||
describe('decoding', (): void => {
|
||||
const testDecode = (type: string, input: unknown, output: string): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const s = new BTreeSet(registry, U32, input as string);
|
||||
|
||||
expect(s.toString()).toBe(output);
|
||||
});
|
||||
|
||||
testDecode('Set', mockU32Set, mockU32SetString);
|
||||
testDecode('hex', mockU32SetHexString, mockU32SetString);
|
||||
testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
|
||||
|
||||
testDecode('Set', mockU32Set, mockU32SetString);
|
||||
testDecode('hex', mockU32SetHexString, mockU32SetString);
|
||||
testDecode('Uint8Array', mockU32SetUint8Array, mockU32SetString);
|
||||
});
|
||||
|
||||
describe('encoding multiple values', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const s = new BTreeSet(registry, U32, mockU32Set);
|
||||
|
||||
expect(s[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', mockU32SetHexString);
|
||||
testEncode('toJSON', mockU32SetObject);
|
||||
testEncode('toU8a', mockU32SetUint8Array);
|
||||
testEncode('toString', mockU32SetString);
|
||||
});
|
||||
|
||||
it('decodes null', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeSet.with(U32)
|
||||
)(registry, null).toString()
|
||||
).toEqual('[]');
|
||||
});
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new BTreeSet(registry, Text, new Set([foo]))).eq(new Set([foo]))
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('decodes within more complicated types', (): void => {
|
||||
const s = new Struct(registry, {
|
||||
placeholder: U32,
|
||||
value: BTreeSet.with(U32)
|
||||
});
|
||||
|
||||
s.set('value', new BTreeSet(registry, U32, mockU32Set));
|
||||
expect(s.toString()).toBe('{"placeholder":0,"value":[2,24,30,80]}');
|
||||
});
|
||||
|
||||
it('throws when it cannot decode', (): void => {
|
||||
expect(
|
||||
(): BTreeSet<U32> => new (
|
||||
BTreeSet.with(U32)
|
||||
)(registry, 'ABC')
|
||||
).toThrowError(/BTreeSet: cannot decode type/);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(
|
||||
new (
|
||||
BTreeSet.with(U32))(registry, mockU32Set).encodedLength
|
||||
).toEqual(17);
|
||||
});
|
||||
|
||||
it('correctly sorts numeric values', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeSet.with(I32))(registry, mockI32SetObj)).map((k) => k.toNumber())
|
||||
).toEqual([-1000, -255, 0, 255, 1000]);
|
||||
});
|
||||
|
||||
it('correctly sorts text values', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeSet.with(Text))(registry, mockTextSetObj)).map((k) => k.toString())
|
||||
).toEqual(['b', 'ba', 'baz', 'bb', 'c']);
|
||||
});
|
||||
|
||||
it('correctly sorts complex tuple values', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeSet.with(U32TextTuple))(registry, mockTupleSetObj)).map((k) => k.toJSON())
|
||||
).toEqual([[1, 'baz'], [2, 'b'], [2, 'ba'], [2, 'bb']]);
|
||||
});
|
||||
|
||||
it('correctly sorts complex struct values', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeSet.with(MockStruct))(registry, mockStructSetObj)).map((k) => k.toJSON())
|
||||
).toEqual([
|
||||
{ int: -1, text: 'b' },
|
||||
{ int: 1, text: 'b' },
|
||||
{ int: -1, text: 'ba' },
|
||||
{ int: -2, text: 'baz' }
|
||||
]);
|
||||
});
|
||||
|
||||
it('correctly sorts complex enum values', (): void => {
|
||||
expect(
|
||||
Array.from(new (BTreeSet.with(MockEnum))(registry, mockEnumSetObj)).map((k) => k.toJSON())
|
||||
).toEqual([
|
||||
{ key1: { int: -1, text: 'b' } },
|
||||
{ key1: { int: 1, text: 'b' } },
|
||||
{ key2: { int: -1, text: 'b' } },
|
||||
{ key3: [2, 'b'] },
|
||||
{ key3: [2, 'ba'] }
|
||||
]);
|
||||
});
|
||||
|
||||
it('generates sane toRawTypes', (): void => {
|
||||
expect(new (BTreeSet.with(U32))(registry).toRawType()).toBe('BTreeSet<u32>');
|
||||
expect(new (BTreeSet.with(Text))(registry).toRawType()).toBe('BTreeSet<Text>');
|
||||
expect(new (BTreeSet.with(Struct.with({ a: U32, b: Text })))(registry).toRawType())
|
||||
.toBe('BTreeSet<{"a":"u32","b":"Text"}>');
|
||||
});
|
||||
});
|
||||
@@ -1,81 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { CodecDate } from '@polkadot/types-codec';
|
||||
import { BN } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { U32 } from '../primitive';
|
||||
import { Compact } from '.';
|
||||
|
||||
describe('Compact', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('constructor', (): void => {
|
||||
it('has support for BigInt', (): void => {
|
||||
expect(
|
||||
new Compact(registry, 'u128', 123456789000123456789n).toHuman()
|
||||
).toEqual('123,456,789,000,123,456,789');
|
||||
});
|
||||
|
||||
it('has the correct bitLength for constructor values (BlockNumber)', (): void => {
|
||||
expect(
|
||||
new (Compact.with(registry.createClass('BlockNumber')))(registry, 0xfffffff9).bitLength()
|
||||
).toEqual(32);
|
||||
});
|
||||
|
||||
it('has the correct encodedLength for constructor values (string BlockNumber)', (): void => {
|
||||
expect(
|
||||
new (Compact.with('BlockNumber'))(registry, 0xfffffff9).encodedLength
|
||||
).toEqual(5);
|
||||
});
|
||||
|
||||
it('has the correct encodedLength for constructor values (class BlockNumber)', (): void => {
|
||||
expect(
|
||||
new (Compact.with(registry.createClass('BlockNumber')))(registry, 0xfffffff9).encodedLength
|
||||
).toEqual(5);
|
||||
});
|
||||
|
||||
it('has the correct encodedLength for constructor values (u32)', (): void => {
|
||||
expect(
|
||||
new (Compact.with(U32))(registry, 0xffff9).encodedLength
|
||||
).toEqual(4);
|
||||
});
|
||||
|
||||
it('constructs properly via Uint8Array as U32', (): void => {
|
||||
expect(
|
||||
new (Compact.with(U32))(registry, new Uint8Array([254, 255, 3, 0])).toNumber()
|
||||
).toEqual(new BN(0xffff).toNumber());
|
||||
});
|
||||
|
||||
it('constructs properly via number as Moment', (): void => {
|
||||
expect(
|
||||
new (Compact.with(CodecDate))(registry, 1537968546).toString().startsWith('Wed Sep 26 2018') // The time depends on the timezone this test is run in
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against another Compact', (): void => {
|
||||
expect(new (Compact.with(U32))(registry, 12345).eq(new (Compact.with(U32))(registry, 12345))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against a primitive', (): void => {
|
||||
expect(new (Compact.with(U32))(registry, 12345).eq(12345)).toBe(true);
|
||||
});
|
||||
|
||||
it('unwraps to the wrapped value', (): void => {
|
||||
expect(new (Compact.with(U32))(registry, 12345).unwrap() instanceof U32).toBe(true);
|
||||
});
|
||||
|
||||
it('has a valid toBn interface', (): void => {
|
||||
expect(new (Compact.with('u128'))(registry, '12345678987654321').toBn().eq(new BN('12345678987654321'))).toBe(true);
|
||||
});
|
||||
|
||||
it('has a valid toBigInt interface', (): void => {
|
||||
expect(
|
||||
(new (Compact.with('u128'))(registry, 12345678987654321n).toBigInt() + 1n) === 12345678987654322n
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { CodecDate } from '@polkadot/types-codec';
|
||||
import { BN } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { U64 } from '../primitive';
|
||||
|
||||
describe('Date', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('decode', (): void => {
|
||||
const testDecode = (type: string, input: Date | CodecDate | U64 | number, expected: string | number, toJSON = false): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
expect(new CodecDate(registry, input)[toJSON ? 'toJSON' : 'toISOString']()).toBe(expected);
|
||||
});
|
||||
|
||||
testDecode('Date', new Date(1537968546280), '2018-09-26T13:29:06.280Z');
|
||||
testDecode('CodecDate', new CodecDate(registry, 1234), 1234, true);
|
||||
testDecode('number', 1234, 1234, true);
|
||||
testDecode('U64', new U64(registry, 69), 69, true);
|
||||
});
|
||||
|
||||
describe('encode', (): void => {
|
||||
const testEncode = (to: 'toBigInt' | 'toBn' | 'toISOString' | 'toNumber' | CodecTo, expected: bigint | BN | number | string | Uint8Array): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
expect(new CodecDate(registry, 421)[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toBigInt', 421n);
|
||||
testEncode('toBn', new BN(421));
|
||||
testEncode('toJSON', 421);
|
||||
testEncode('toISOString', '1970-01-01T00:07:01.000Z');
|
||||
|
||||
testEncode('toNumber', 421);
|
||||
testEncode('toU8a', Uint8Array.from([165, 1, 0, 0, 0, 0, 0, 0]));
|
||||
|
||||
it('can encode toString', (): void => {
|
||||
const date = new Date(Date.UTC(1970, 0, 1, 2, 3, 4));
|
||||
|
||||
date.setTime(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
|
||||
|
||||
expect(
|
||||
new CodecDate(registry, date).toString()
|
||||
).toMatch(/^Thu Jan 01 1970 02:03:04/);
|
||||
});
|
||||
|
||||
it('encodes default BE hex', (): void => {
|
||||
expect(
|
||||
new CodecDate(registry, 3).toHex()
|
||||
).toEqual('0x0000000000000003');
|
||||
});
|
||||
|
||||
it('encodes options LE hex', (): void => {
|
||||
expect(
|
||||
new CodecDate(registry, 3).toHex(true)
|
||||
).toEqual('0x0300000000000000');
|
||||
});
|
||||
|
||||
it('encodes correctly to BigInt', (): void => {
|
||||
expect(
|
||||
new CodecDate(registry, 41).toBigInt() + 1n
|
||||
).toEqual(42n);
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares values', (): void => {
|
||||
expect(new CodecDate(registry, 123).eq(123)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares values (non-match)', (): void => {
|
||||
expect(new CodecDate(registry, 123).eq(456)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { DoNotConstruct } from '.';
|
||||
|
||||
describe('DoNotConstruct', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('does not allow construction', (): void => {
|
||||
expect(
|
||||
() => new (DoNotConstruct.with())(registry)
|
||||
).toThrow(/Cannot construct unknown type DoNotConstruct/);
|
||||
});
|
||||
|
||||
it('does not allow construction (with Name)', (): void => {
|
||||
expect(
|
||||
() => new (DoNotConstruct.with('Something'))(registry)
|
||||
).toThrow(/Cannot construct unknown type Something/);
|
||||
});
|
||||
});
|
||||
@@ -1,442 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecRegistry } from '@polkadot/types-codec/types';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Null, Text, U32 } from '../primitive';
|
||||
import { Enum } from '.';
|
||||
|
||||
describe('Enum', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('typed enum (previously EnumType)', (): void => {
|
||||
it('provides a clean toString() (value)', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
new Uint8Array([0, 2 << 2, 49, 50])
|
||||
).value.toString()
|
||||
).toEqual('12');
|
||||
});
|
||||
|
||||
it('provides a clean toString() (enum)', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
new Uint8Array([1, 2 << 2, 49, 50])
|
||||
).toString()
|
||||
).toEqual('{"u32":3289352}');
|
||||
});
|
||||
|
||||
it('decodes from a JSON input (lowercase)', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
{ text: 'some text value' }
|
||||
).value.toString()
|
||||
).toEqual('some text value');
|
||||
});
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ foo: Text },
|
||||
{ foo }
|
||||
).value
|
||||
).toBe(foo);
|
||||
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ foo: Text },
|
||||
foo,
|
||||
0
|
||||
).value
|
||||
).toBe(foo);
|
||||
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ foo: Text },
|
||||
new Enum(registry, { foo: Text }, { foo })
|
||||
).value
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
it('decodes from hex', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
'0x0134120000'
|
||||
).value.toString()
|
||||
).toEqual('4660'); // 0x1234 in decimal
|
||||
});
|
||||
|
||||
it('decodes from hex (string types)', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
// eslint-disable-next-line sort-keys
|
||||
{ foo: 'Text', bar: 'u32' },
|
||||
'0x0134120000'
|
||||
).value.toString()
|
||||
).toEqual('4660'); // 0x1234 in decimal
|
||||
});
|
||||
|
||||
it('decodes from a JSON input (mixed case)', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
{ U32: 42 }
|
||||
).value.toString()
|
||||
).toEqual('42');
|
||||
});
|
||||
|
||||
it('decodes from JSON string', (): void => {
|
||||
expect(
|
||||
new Enum(
|
||||
registry,
|
||||
{ Null, U32 },
|
||||
'null'
|
||||
).type
|
||||
).toEqual('Null');
|
||||
});
|
||||
|
||||
it('has correct isXyz/asXyz (Enum.with)', (): void => {
|
||||
const test = new (Enum.with({ First: Text, Second: U32, Third: U32 }))(registry, { Second: 42 }) as any as { isFirst: boolean; isSecond: boolean; asSecond: U32; isThird: boolean; asThird: never };
|
||||
const asKeys = Object.keys(test).filter((k) => k.startsWith('as'));
|
||||
const isKeys = Object.keys(test).filter((k) => k.startsWith('is'));
|
||||
|
||||
expect(asKeys).toEqual(['asFirst', 'asSecond', 'asThird']);
|
||||
expect(isKeys).toEqual(['isFirst', 'isSecond', 'isThird']);
|
||||
expect([test.isFirst, test.isSecond, test.isThird]).toEqual([false, true, false]);
|
||||
|
||||
expect(test.asSecond.toNumber()).toEqual(42);
|
||||
expect((): never => test.asThird).toThrow(/Cannot convert 'Second' via asThird/);
|
||||
});
|
||||
|
||||
it('stringifies with custom types', (): void => {
|
||||
class A extends Null { }
|
||||
class B extends Null { }
|
||||
class C extends Null { }
|
||||
class Test extends Enum {
|
||||
constructor (registry: CodecRegistry, value?: string, index?: number) {
|
||||
super(registry, {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C
|
||||
}, value, index);
|
||||
}
|
||||
}
|
||||
|
||||
expect(new Test(registry).toJSON()).toEqual({ a: null });
|
||||
});
|
||||
|
||||
it('creates via with', (): void => {
|
||||
class A extends Null { }
|
||||
class B extends U32 { }
|
||||
class C extends Null { }
|
||||
const Test = Enum.with({ A, B, C });
|
||||
|
||||
expect(new Test(registry).toJSON()).toEqual({ a: null });
|
||||
expect(new Test(registry, 1234, 1).toJSON()).toEqual({ b: 1234 });
|
||||
expect(new Test(registry, 0x1234, 1).toU8a()).toEqual(new Uint8Array([1, 0x34, 0x12, 0x00, 0x00]));
|
||||
expect(new Test(registry, 0x1234, 1).toU8a(true)).toEqual(new Uint8Array([0x34, 0x12, 0x00, 0x00]));
|
||||
});
|
||||
|
||||
it('allows accessing the type and value', (): void => {
|
||||
const text = new Text(registry, 'foo');
|
||||
const enumType = new Enum(
|
||||
registry,
|
||||
{ Text, U32 },
|
||||
{ Text: text }
|
||||
);
|
||||
|
||||
expect(enumType.type).toBe('Text');
|
||||
expect(enumType.value).toEqual(text);
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
const DEF = { num: U32, str: Text };
|
||||
const u8a = new Uint8Array([1, 3 << 2, 88, 89, 90]);
|
||||
const test = new Enum(registry, DEF, u8a);
|
||||
|
||||
it('compares against index', (): void => {
|
||||
expect(test.eq(1)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against u8a', (): void => {
|
||||
expect(test.eq(u8a)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against hex', (): void => {
|
||||
expect(test.eq(u8aToHex(u8a))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against another enum', (): void => {
|
||||
expect(test.eq(new Enum(registry, DEF, u8a))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against another object', (): void => {
|
||||
expect(test.eq({ str: 'XYZ' })).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against values', (): void => {
|
||||
expect(test.eq('XYZ')).toBe(true);
|
||||
});
|
||||
|
||||
it('compares basic enum on string', (): void => {
|
||||
expect(new Enum(registry, ['A', 'B', 'C'], 1).eq('B')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('string-only construction (old Enum)', (): void => {
|
||||
const testDecode = (type: string, input: any, expected: any): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const e = new Enum(registry, ['foo', 'bar'], input);
|
||||
|
||||
expect(e.toString()).toBe(expected);
|
||||
});
|
||||
|
||||
const testEncode = (to: 'toJSON' | 'toNumber' | 'toString' | 'toU8a', expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const e = new Enum(registry, ['Foo', 'Bar'], 1);
|
||||
|
||||
expect(e[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testDecode('Enum', undefined, 'foo');
|
||||
testDecode('Enum', new Enum(registry, ['foo', 'bar'], 1), 'bar');
|
||||
testDecode('number', 0, 'foo');
|
||||
testDecode('number', 1, 'bar');
|
||||
testDecode('string', 'bar', 'bar');
|
||||
testDecode('Uint8Array', Uint8Array.from([0]), 'foo');
|
||||
testDecode('Uint8Array', Uint8Array.from([1]), 'bar');
|
||||
|
||||
testEncode('toJSON', 'Bar');
|
||||
testEncode('toNumber', 1);
|
||||
testEncode('toString', 'Bar');
|
||||
testEncode('toU8a', Uint8Array.from([1]));
|
||||
|
||||
it('provides a clean toString()', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar']).toString()
|
||||
).toEqual('foo');
|
||||
});
|
||||
|
||||
it('provides a clean toString() (enum)', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], new Enum(registry, ['foo', 'bar'], 1)).toNumber()
|
||||
).toEqual(1);
|
||||
});
|
||||
|
||||
it('converts to and from Uint8Array', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], new Uint8Array([1])).toU8a()
|
||||
).toEqual(new Uint8Array([1]));
|
||||
});
|
||||
|
||||
it('converts from JSON', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar', 'baz', 'gaz', 'jaz'], 4).toNumber()
|
||||
).toEqual(4);
|
||||
});
|
||||
|
||||
it('has correct isXyz getters (Enum.with)', (): void => {
|
||||
const test = new (Enum.with(['First', 'Second', 'Third']))(registry, 'Second') as any as { isFirst: boolean; isSecond: boolean; isThird: boolean };
|
||||
|
||||
expect([test.isFirst, test.isSecond, test.isThird]).toEqual([false, true, false]);
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against the index value', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], 1).eq(1)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against the index value (false)', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], 1).eq(0)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('compares against the string value', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], 1).eq('bar')
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against the string value (false)', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar'], 1).eq('foo')
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('has isNone set, with correct index (i.e. no values are used)', (): void => {
|
||||
const test = new Enum(registry, ['foo', 'bar'], 1);
|
||||
|
||||
expect(test.isNone).toBe(true);
|
||||
expect(test.index).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('index construction', (): void => {
|
||||
it('creates enum where index is specified', (): void => {
|
||||
const Test = Enum.with({
|
||||
A: U32,
|
||||
B: U32
|
||||
});
|
||||
const test = new Test(registry, new U32(registry, 123), 1);
|
||||
|
||||
expect(test.type).toEqual('B');
|
||||
expect((test.value as U32).toNumber()).toEqual(123);
|
||||
});
|
||||
|
||||
it('creates enum when value is an enum', (): void => {
|
||||
const Test = Enum.with({
|
||||
A: U32,
|
||||
B: U32
|
||||
});
|
||||
const test = new Test(registry, new Test(registry, 123, 1));
|
||||
|
||||
expect(test.type).toEqual('B');
|
||||
expect((test.value as U32).toNumber()).toEqual(123);
|
||||
});
|
||||
|
||||
it('creates via enum with nested enums as the value', (): void => {
|
||||
const Nest = Enum.with({
|
||||
C: U32,
|
||||
D: U32
|
||||
});
|
||||
const Test = Enum.with({
|
||||
A: U32,
|
||||
B: Nest
|
||||
});
|
||||
const test = new Test(registry, new Nest(registry, 123, 1), 1);
|
||||
|
||||
expect(test.type).toEqual('B');
|
||||
expect((test.value as Enum).type).toEqual('D');
|
||||
expect(((test.value as Enum).value as U32).toNumber()).toEqual(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toRawType', (): void => {
|
||||
it('has a sane output for basic enums', (): void => {
|
||||
expect(
|
||||
new Enum(registry, ['foo', 'bar']).toRawType()
|
||||
).toEqual(JSON.stringify({ _enum: ['foo', 'bar'] }));
|
||||
});
|
||||
|
||||
it('has a sane output for typed enums', (): void => {
|
||||
expect(
|
||||
// eslint-disable-next-line sort-keys
|
||||
new Enum(registry, { foo: Text, bar: U32 }).toRawType()
|
||||
// eslint-disable-next-line sort-keys
|
||||
).toEqual(JSON.stringify({ _enum: { foo: 'Text', bar: 'u32' } }));
|
||||
});
|
||||
|
||||
it('re-creates via rawType (c-like)', (): void => {
|
||||
const type = new Enum(registry, ['foo', 'bar']).toRawType() as 'Raw';
|
||||
|
||||
expect(registry.createType(type, 1).toString()).toEqual('bar');
|
||||
});
|
||||
|
||||
it('re-creates via rawType (types)', (): void => {
|
||||
const type = new Enum(registry, { A: Text, B: U32, C: U32 }).toRawType();
|
||||
const value = registry.createType(type, { B: 123 });
|
||||
|
||||
expect((value as unknown as Record<string, unknown>).isB).toEqual(true);
|
||||
expect((value as unknown as Record<string, U32>).asB.toNumber()).toEqual(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe('indexed enum', (): void => {
|
||||
const Test = Enum.with({
|
||||
A: 5,
|
||||
B: 42,
|
||||
C: 69,
|
||||
D: 255
|
||||
});
|
||||
|
||||
it('handles an indexed C-like enum', (): void => {
|
||||
expect(new Test(registry, 'A').toNumber()).toEqual(5);
|
||||
expect(new Test(registry, 'B').toNumber()).toEqual(42);
|
||||
expect(new Test(registry, 'C').toNumber()).toEqual(69);
|
||||
expect(new Test(registry, 69).toNumber()).toEqual(69);
|
||||
expect(new Test(registry, 'D').toNumber()).toEqual(255);
|
||||
});
|
||||
|
||||
it('creates proper raw structure', (): void => {
|
||||
expect(new Test(registry).toRawType()).toEqual(JSON.stringify({
|
||||
_enum: {
|
||||
A: 5,
|
||||
B: 42,
|
||||
C: 69,
|
||||
D: 255
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
it('has the indexes for the enum', (): void => {
|
||||
expect(new Test(registry).defIndexes).toEqual([5, 42, 69, 255]);
|
||||
});
|
||||
|
||||
it('has the correct outputs', (): void => {
|
||||
const test = new Test(registry, 5);
|
||||
|
||||
expect(test.toU8a()).toEqual(new Uint8Array([5]));
|
||||
expect(test.toHex()).toEqual('0x05');
|
||||
expect(test.toJSON()).toEqual('A');
|
||||
});
|
||||
});
|
||||
|
||||
describe('toHex', (): void => {
|
||||
it('has a proper hex representation & length', (): void => {
|
||||
const Test = Enum.with({
|
||||
A: Text,
|
||||
B: U32
|
||||
});
|
||||
const test = new Test(registry, 123, 1);
|
||||
|
||||
expect(test.toHex()).toEqual('0x017b000000');
|
||||
expect(test.encodedLength).toEqual(1 + 4);
|
||||
});
|
||||
|
||||
it('encodes a single entry correctly', (): void => {
|
||||
const Test = Enum.with({ A: 'u32' });
|
||||
const test = new Test(registry, 0x44332211, 0);
|
||||
|
||||
expect(test.toHex()).toEqual(
|
||||
'0x' +
|
||||
'00' + // index
|
||||
'11223344' // u32 LE encoded
|
||||
);
|
||||
});
|
||||
|
||||
it('encodes a single entry correctly (with embedded encoding)', (): void => {
|
||||
const Test = Enum.with({ A: 'MultiAddress' });
|
||||
const test = new Test(registry, registry.createType('AccountId', '0x0001020304050607080910111213141516171819202122232425262728293031'), 0);
|
||||
|
||||
expect(test.toHex()).toEqual(
|
||||
'0x' +
|
||||
'00' + // index
|
||||
'00' + // MultiAddress indicating an embedded AccountId
|
||||
'0001020304050607080910111213141516171819202122232425262728293031' // AccountId
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, U32 } from '../primitive';
|
||||
import { HashMap, Struct } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('HashMap', (): void => {
|
||||
it('generates sane toRawTypes', (): void => {
|
||||
expect(new (HashMap.with(Text, U32))(registry).toRawType()).toBe('HashMap<Text,u32>');
|
||||
expect(new (HashMap.with(Text, Text))(registry).toRawType()).toBe('HashMap<Text,Text>');
|
||||
expect(new (HashMap.with(Text, Struct.with({ a: U32, b: Text })))(registry).toRawType())
|
||||
.toBe('HashMap<Text,{"a":"u32","b":"Text"}>');
|
||||
});
|
||||
});
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Int } from '.';
|
||||
|
||||
describe('Int', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('provides a toBigInt interface', (): void => {
|
||||
expect(
|
||||
new Int(registry, -1234).toBigInt()
|
||||
).toEqual(-1234n);
|
||||
});
|
||||
|
||||
it('provides a toBn interface', (): void => {
|
||||
expect(
|
||||
new Int(registry, -1234).toBn().toNumber()
|
||||
).toEqual(-1234);
|
||||
});
|
||||
|
||||
it('provides a toNumber interface', (): void => {
|
||||
expect(
|
||||
new Int(registry, -1234).toNumber()
|
||||
).toEqual(-1234);
|
||||
});
|
||||
|
||||
it('converts to Little Endian from the provided value', (): void => {
|
||||
expect(
|
||||
new Int(registry, -1234).toU8a()
|
||||
).toEqual(new Uint8Array([46, 251, 255, 255, 255, 255, 255, 255]));
|
||||
});
|
||||
|
||||
it('converts to Little Endian from the provided value (bitLength)', (): void => {
|
||||
expect(
|
||||
new Int(registry, -1234, 32).toU8a()
|
||||
).toEqual(new Uint8Array([46, 251, 255, 255]));
|
||||
});
|
||||
|
||||
it('converts to hex/string', (): void => {
|
||||
const i = new Int(registry, '0x12', 16);
|
||||
|
||||
expect(i.toHex()).toEqual('0x0012');
|
||||
expect(i.toString()).toEqual('18');
|
||||
});
|
||||
|
||||
it('converts to equivalents', (): void => {
|
||||
const a = new Int(registry, '-123');
|
||||
|
||||
expect(
|
||||
new Int(registry, a).toNumber()
|
||||
).toEqual(-123);
|
||||
});
|
||||
|
||||
describe('static with', (): void => {
|
||||
it('allows default toRawType', (): void => {
|
||||
expect(
|
||||
new (Int.with(64))(registry).toRawType()
|
||||
).toEqual('i64');
|
||||
});
|
||||
|
||||
it('allows toRawType override', (): void => {
|
||||
expect(
|
||||
new (Int.with(64, 'SomethingElse'))(registry).toRawType()
|
||||
).toEqual('SomethingElse');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create/registry';
|
||||
import { Linkage } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('Linkage', (): void => {
|
||||
it('decodes with ValidatorPrefs', (): void => {
|
||||
const LINKA = { next: '5GznmRvdi5htUJKnMSWJgJUzSJJXSvWuHRSEdyUbHJZDNcwU', previous: null };
|
||||
const PREFS = { commission: '10.00%' };
|
||||
|
||||
// prefs sanity check
|
||||
expect(
|
||||
registry.createType(
|
||||
'ValidatorPrefsWithCommission',
|
||||
'0x0284d717'
|
||||
).toHuman()
|
||||
).toEqual(PREFS);
|
||||
|
||||
// linkage sanity checks
|
||||
expect(
|
||||
new Linkage(registry, 'AccountId', '0x0001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36').toHuman()
|
||||
).toEqual(LINKA);
|
||||
expect(
|
||||
registry.createType(
|
||||
'Linkage<AccountId>',
|
||||
'0x0001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36'
|
||||
).toHuman()
|
||||
).toEqual(LINKA);
|
||||
|
||||
// actual check
|
||||
expect(
|
||||
registry.createType(
|
||||
'(ValidatorPrefsWithCommission, Linkage<AccountId>)',
|
||||
'0x0284d7170001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36'
|
||||
).toHuman()
|
||||
).toEqual([PREFS, LINKA]);
|
||||
});
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, U32 } from '../primitive';
|
||||
import { CodecMap } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
const mockU32TextMap = new Map<Text, U32>();
|
||||
|
||||
mockU32TextMap.set(new Text(registry, 'bazzing'), new U32(registry, 69));
|
||||
|
||||
const mockU32TextMapString = '{"bazzing":69}';
|
||||
const mockU32TextMapObject = { bazzing: 69 };
|
||||
const mockU32TextMapHexString = '0x041c62617a7a696e6745000000';
|
||||
const mockU32TextMapUint8Array = Uint8Array.from([4, 28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0]);
|
||||
|
||||
const mockU32U32Map = new Map<U32, U32>();
|
||||
|
||||
mockU32U32Map.set(new U32(registry, 1), new U32(registry, 2));
|
||||
mockU32U32Map.set(new U32(registry, 23), new U32(registry, 24));
|
||||
mockU32U32Map.set(new U32(registry, 28), new U32(registry, 30));
|
||||
mockU32U32Map.set(new U32(registry, 45), new U32(registry, 80));
|
||||
|
||||
const mockU32U32MapString = '{"1":2,"23":24,"28":30,"45":80}';
|
||||
const mockU32U32MapObject = { 1: 2, 23: 24, 28: 30, 45: 80 };
|
||||
const mockU32U32MapHexString = '0x10043102000000083233180000000832381e00000008343550000000';
|
||||
const mockU32U32MapUint8Array = Uint8Array.from([16, 4, 49, 2, 0, 0, 0, 8, 50, 51, 24, 0, 0, 0, 8, 50, 56, 30, 0, 0, 0, 8, 52, 53, 80, 0, 0, 0]);
|
||||
|
||||
describe('CodecMap', (): void => {
|
||||
describe('decoding', (): void => {
|
||||
const testDecode = (type: string, input: unknown, output: string): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const s = new CodecMap(registry, Text, U32, input as string);
|
||||
|
||||
expect(s.toString()).toBe(output);
|
||||
});
|
||||
|
||||
testDecode('map', mockU32TextMap, mockU32TextMapString);
|
||||
testDecode('hex', mockU32TextMapHexString, mockU32TextMapString);
|
||||
testDecode('Uint8Array', mockU32TextMapUint8Array, mockU32TextMapString);
|
||||
|
||||
testDecode('map', mockU32U32Map, mockU32U32MapString);
|
||||
testDecode('hex', mockU32U32MapHexString, mockU32U32MapString);
|
||||
testDecode('Uint8Array', mockU32U32MapUint8Array, mockU32U32MapString);
|
||||
});
|
||||
|
||||
describe('encoding', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const s = new CodecMap(registry, Text, U32, mockU32TextMap, 'BTreeMap');
|
||||
|
||||
expect(s[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', mockU32TextMapHexString);
|
||||
testEncode('toJSON', mockU32TextMapObject);
|
||||
testEncode('toU8a', mockU32TextMapUint8Array);
|
||||
testEncode('toString', mockU32TextMapString);
|
||||
});
|
||||
|
||||
describe('encoding muple values', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const s = new CodecMap(registry, Text, U32, mockU32U32Map, 'BTreeMap');
|
||||
|
||||
expect(s[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', mockU32U32MapHexString);
|
||||
testEncode('toJSON', mockU32U32MapObject);
|
||||
testEncode('toU8a', mockU32U32MapUint8Array);
|
||||
testEncode('toString', mockU32U32MapString);
|
||||
});
|
||||
});
|
||||
@@ -1,150 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Bytes, Text, U32 } from '../primitive';
|
||||
import { Option } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
const testDecode = (type: string, input: any, expected: string): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const o = new Option(registry, Text, input);
|
||||
|
||||
expect(o.toString()).toBe(expected);
|
||||
expect(o.isNone).toBe(!expected.length);
|
||||
});
|
||||
|
||||
const testEncode = (to: 'toHex' | 'toString' | 'toU8a', expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const e = new Option(registry, Text, 'foo');
|
||||
|
||||
expect(e[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
describe('Option', (): void => {
|
||||
it('converts undefined/null to empty', (): void => {
|
||||
expect(new Option(registry, Text, undefined).isNone).toBe(true);
|
||||
expect(new Option(registry, Text, null).isNone).toBe(true);
|
||||
expect(new Option(registry, Text, 'test').isNone).toBe(false);
|
||||
expect(new Option(registry, Text, '0x').isNone).toBe(true);
|
||||
});
|
||||
|
||||
it('converts an option to an option', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text, new Option(registry, Text, 'hello')).toString()
|
||||
).toEqual('hello');
|
||||
});
|
||||
|
||||
it('converts an option to an option (strings)', (): void => {
|
||||
expect(
|
||||
new Option(registry, 'Text', new Option(registry, 'Text', 'hello')).toString()
|
||||
).toEqual('hello');
|
||||
});
|
||||
|
||||
it('converts correctly from hex with toHex (Bytes)', (): void => {
|
||||
// Option<Bytes> for a parachain head, however, this is effectively an
|
||||
// Option<Option<Bytes>> (hence the length, since it is from storage)
|
||||
const HEX = '0x210100000000000000000000000000000000000000000000000000000000000000000000000000000000011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce';
|
||||
|
||||
// watch the hex prefix and length
|
||||
expect(
|
||||
new Option(registry, Bytes, HEX).toHex().substr(6)
|
||||
).toEqual(HEX.substr(2));
|
||||
});
|
||||
|
||||
it('converts correctly from hex with toNumber (U64)', (): void => {
|
||||
const HEX = '0x12345678';
|
||||
|
||||
expect(
|
||||
new Option(registry, U32, HEX).unwrap().toNumber()
|
||||
).toEqual(0x12345678);
|
||||
});
|
||||
|
||||
it('decodes reusing instanciated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new Option(registry, Text, foo)).value
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
testDecode('string (with)', 'foo', 'foo');
|
||||
testDecode('string (without)', undefined, '');
|
||||
testDecode('Uint8Array (with)', Uint8Array.from([1, 12, 102, 111, 111]), 'foo');
|
||||
testDecode('Uint8Array (without)', Uint8Array.from([0]), '');
|
||||
|
||||
testEncode('toHex', '0x0c666f6f');
|
||||
testEncode('toString', 'foo');
|
||||
testEncode('toU8a', Uint8Array.from([1, 12, 102, 111, 111]));
|
||||
|
||||
it('has empty toString() (undefined)', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text).toString()
|
||||
).toEqual('');
|
||||
});
|
||||
|
||||
it('has value toString() (provided)', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text, new Uint8Array([1, 4 << 2, 49, 50, 51, 52])).toString()
|
||||
).toEqual('1234');
|
||||
});
|
||||
|
||||
it('converts toU8a() with', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text, '1234').toU8a()
|
||||
).toEqual(new Uint8Array([1, 4 << 2, 49, 50, 51, 52]));
|
||||
});
|
||||
|
||||
it('converts toU8a() without', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text).toU8a()
|
||||
).toEqual(new Uint8Array([0]));
|
||||
});
|
||||
|
||||
it('converts toJSON() as null without', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text).toJSON()
|
||||
).toEqual(null);
|
||||
});
|
||||
|
||||
it('converts toJSON() as non-null with Bytes', (): void => {
|
||||
expect(
|
||||
new Option(registry, Bytes, 'abcde').toJSON()
|
||||
).toEqual('0x6162636465');
|
||||
});
|
||||
|
||||
it('converts toJSON() as non-null with Text', (): void => {
|
||||
expect(
|
||||
new Option(registry, Text, 'abcde').toJSON()
|
||||
).toEqual('abcde');
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
const test = new Option(registry, Text, '1234');
|
||||
|
||||
it('compares against other option', (): void => {
|
||||
expect(test.eq(new Option(registry, Text, '1234'))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against raw value', (): void => {
|
||||
expect(test.eq('1234')).toBe(true);
|
||||
});
|
||||
|
||||
it('unwrapOr to specified if empty', (): void => {
|
||||
expect(new Option(registry, Text).unwrapOr('6789').toString()).toEqual('6789');
|
||||
});
|
||||
|
||||
it('unwrapOr to specified if non-empty', (): void => {
|
||||
expect(new Option(registry, Text, '1234').unwrapOr(null)?.toString()).toEqual('1234');
|
||||
});
|
||||
|
||||
it('unwrapOrDefault to default if empty', (): void => {
|
||||
expect(new Option(registry, U32).unwrapOrDefault().toNumber()).toEqual(0);
|
||||
});
|
||||
|
||||
it('unwrapOrDefault to specified if non-empty', (): void => {
|
||||
expect(new Option(registry, U32, '1234').unwrapOrDefault().toNumber()).toEqual(1234);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { U32 } from '../primitive';
|
||||
import { Range } from '.';
|
||||
|
||||
describe('Range', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
let range: Range<U32>;
|
||||
|
||||
beforeEach((): void => {
|
||||
const Clazz = Range.with(U32);
|
||||
|
||||
range = new Clazz(
|
||||
registry,
|
||||
[new U32(registry, 1), new U32(registry, 2)]
|
||||
);
|
||||
});
|
||||
|
||||
it('decodes', (): void => {
|
||||
expect(range.toJSON()).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
it('encodes', (): void => {
|
||||
expect(range.toU8a()).toEqual(new Uint8Array([1, 0, 0, 0, 2, 0, 0, 0]));
|
||||
});
|
||||
|
||||
it('has a sane toRawType representation', (): void => {
|
||||
expect(range.toRawType()).toEqual('Range<u32>');
|
||||
});
|
||||
});
|
||||
@@ -1,93 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AnyU8a, CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Raw } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
const testDecode = (type: string, input: AnyU8a, expected: string): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const e = new Raw(registry, input);
|
||||
|
||||
expect(e.toString()).toBe(expected);
|
||||
});
|
||||
|
||||
const testEncode = (to: CodecTo, expected: AnyU8a): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const e = new Raw(registry, [1, 2, 3, 4, 5]);
|
||||
|
||||
expect(e[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
describe('Raw', (): void => {
|
||||
let u8a: Raw;
|
||||
|
||||
beforeEach((): void => {
|
||||
u8a = new Raw(registry, [1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
testDecode('Array', [1, 2, 3, 4, 5], '0x0102030405');
|
||||
testDecode('hex', '0x0102030405', '0x0102030405');
|
||||
testDecode('U8a', new Uint8Array([1, 2, 3, 4, 5]), '0x0102030405');
|
||||
testDecode('Uint8Array', Uint8Array.from([1, 2, 3, 4, 5]), '0x0102030405');
|
||||
|
||||
testEncode('toJSON', '0x0102030405');
|
||||
testEncode('toHex', '0x0102030405');
|
||||
testEncode('toString', '0x0102030405');
|
||||
testEncode('toU8a', Uint8Array.from([1, 2, 3, 4, 5]));
|
||||
|
||||
it('contains the length of the elements', (): void => {
|
||||
expect(u8a.length).toEqual(5);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(u8a.encodedLength).toEqual(5);
|
||||
});
|
||||
|
||||
it('allows wrapping of a pre-existing instance', (): void => {
|
||||
expect(
|
||||
new Raw(registry, u8a).length
|
||||
).toEqual(5);
|
||||
});
|
||||
|
||||
it('implements subarray correctly', (): void => {
|
||||
expect(u8a.subarray(1, 3)).toEqual(Uint8Array.from([2, 3]));
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against other U8a', (): void => {
|
||||
expect(u8a.eq(new Uint8Array([1, 2, 3, 4, 5]))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against other U8a (non-length)', (): void => {
|
||||
expect(u8a.eq(new Uint8Array([1, 2, 3, 4]))).toBe(false);
|
||||
});
|
||||
|
||||
it('compares against other U8a (mismatch)', (): void => {
|
||||
expect(u8a.eq(new Uint8Array([1, 2, 3, 4, 6]))).toBe(false);
|
||||
});
|
||||
|
||||
it('compares against hex inputs', (): void => {
|
||||
expect(u8a.eq('0x0102030405')).toBe(true);
|
||||
});
|
||||
|
||||
it('has valid isAscii', (): void => {
|
||||
expect(u8a.isAscii).toBe(false);
|
||||
expect(new Raw(registry, '0x2021222324').isAscii).toBe(true);
|
||||
});
|
||||
|
||||
it('has valid toUtf8', (): void => {
|
||||
expect(new Raw(registry, 'Приветствую, ми').toUtf8()).toEqual('Приветствую, ми');
|
||||
expect(new Raw(registry, '0xe4bda0e5a5bd').toUtf8()).toEqual('你好');
|
||||
});
|
||||
|
||||
it('throws on invalid utf8', (): void => {
|
||||
expect(
|
||||
() => new Raw(registry, '0x7f07b1f87709608bee603bbc79a0dfc29cd315c1351a83aa31adf7458d7d3003').toUtf8()
|
||||
).toThrow(/The character sequence is not a valid Utf8 string/);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { hexToString } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, u32 } from '../primitive';
|
||||
import { Result } from '.';
|
||||
|
||||
describe('Result', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
const Type = Result.with({ Err: Text, Ok: u32 });
|
||||
|
||||
it('has a sane toRawType representation', (): void => {
|
||||
expect(new Type(registry).toRawType()).toEqual('Result<u32,Text>');
|
||||
});
|
||||
|
||||
it('decodes from a u8a (success)', (): void => {
|
||||
const result = new Type(registry, new Uint8Array([0, 1, 2, 3, 4]));
|
||||
|
||||
expect(result.isOk);
|
||||
expect(result.asOk.toU8a()).toEqual(new Uint8Array([1, 2, 3, 4]));
|
||||
expect(result.toHex()).toEqual('0x0001020304');
|
||||
expect(result.toJSON()).toEqual({
|
||||
ok: 0x04030201
|
||||
});
|
||||
});
|
||||
|
||||
it('decodes from a u8a (error)', (): void => {
|
||||
const result = new Type(registry, new Uint8Array([1, 4 << 2, 100, 101, 102, 103]));
|
||||
|
||||
expect(result.isErr);
|
||||
expect(result.asErr.toU8a()).toEqual(new Uint8Array([4 << 2, 100, 101, 102, 103]));
|
||||
expect(result.toHex()).toEqual('0x011064656667');
|
||||
expect(result.toJSON()).toEqual({
|
||||
err: hexToString('0x64656667')
|
||||
});
|
||||
});
|
||||
|
||||
it('decodes from a JSON representation', (): void => {
|
||||
const result = new Type(registry, { Err: 'error' });
|
||||
|
||||
expect(result.isErr).toBe(true);
|
||||
expect(result.isError).toBe(true);
|
||||
expect(result.asErr.toString()).toEqual('error');
|
||||
expect(result.asError.toString()).toEqual('error');
|
||||
expect(result.toHex()).toEqual('0x01146572726f72');
|
||||
});
|
||||
|
||||
it('decodes reusing instanciated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
new Result(
|
||||
registry,
|
||||
Text,
|
||||
Text,
|
||||
{ Ok: foo }
|
||||
).asOk
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
it('returns a proper raw typedef rom a built-in', (): void => {
|
||||
expect(registry.createType('DispatchResult').toRawType()).toEqual('Result<(),DispatchError>');
|
||||
});
|
||||
});
|
||||
@@ -1,107 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/* eslint-disable sort-keys */
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { CodecSet } from '.';
|
||||
|
||||
// TODO actually import these from definitions, don't re-define here
|
||||
const SET_FIELDS = {
|
||||
header: 0b00000001,
|
||||
body: 0b00000010,
|
||||
receipt: 0b00000100,
|
||||
messageQueue: 0b00001000,
|
||||
justification: 0b00010000
|
||||
};
|
||||
const SET_ROLES = {
|
||||
none: 0b00000000,
|
||||
full: 0b00000001,
|
||||
light: 0b00000010,
|
||||
authority: 0b00000100
|
||||
};
|
||||
const SET_WITHDRAW = {
|
||||
TransactionPayment: 0b00000001,
|
||||
Transfer: 0b00000010,
|
||||
Reserve: 0b00000100,
|
||||
Fee: 0b00001000
|
||||
};
|
||||
|
||||
describe('Set', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('constructs via an string[]', (): void => {
|
||||
const set = new CodecSet(registry, SET_ROLES, ['full', 'authority']);
|
||||
|
||||
expect(set.isEmpty).toEqual(false);
|
||||
expect(set.toString()).toEqual(
|
||||
'[full, authority]'
|
||||
);
|
||||
});
|
||||
|
||||
it('throws with invalid values', (): void => {
|
||||
expect(
|
||||
() => new CodecSet(registry, SET_ROLES, ['full', 'authority', 'invalid'])
|
||||
).toThrow(/Invalid key 'invalid'/);
|
||||
});
|
||||
|
||||
it('throws with add on invalid', (): void => {
|
||||
expect(
|
||||
() => (new CodecSet(registry, SET_ROLES, [])).add('invalid')
|
||||
).toThrow(/Invalid key 'invalid'/);
|
||||
});
|
||||
|
||||
it('allows construction via number', (): void => {
|
||||
expect(
|
||||
(new CodecSet(registry, SET_WITHDRAW, 15)).eq(['TransactionPayment', 'Transfer', 'Reserve', 'Fee'])
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('does not allow invalid number', (): void => {
|
||||
expect(
|
||||
() => new CodecSet(registry, SET_WITHDRAW, 31)
|
||||
).toThrow(/Mismatch decoding '31', computed as '15'/);
|
||||
});
|
||||
|
||||
it('hash a valid encoding', (): void => {
|
||||
const set = new CodecSet(registry, SET_FIELDS, ['header', 'body', 'justification']);
|
||||
|
||||
expect(set.toU8a()).toEqual(new Uint8Array([19]));
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
const set = new CodecSet(registry, SET_ROLES, ['full', 'authority']);
|
||||
|
||||
it('compares against string array', (): void => {
|
||||
expect(
|
||||
set.eq(['authority', 'full'])
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against number (encoded)', (): void => {
|
||||
expect(
|
||||
set.eq(SET_ROLES.full | SET_ROLES.authority)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against other sets', (): void => {
|
||||
expect(
|
||||
set.eq(new CodecSet(registry, SET_ROLES, ['authority', 'full']))
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false on other values', (): void => {
|
||||
expect(
|
||||
set.eq('full')
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('has a sane toRawType representation', (): void => {
|
||||
expect(
|
||||
new CodecSet(registry, { a: 1, b: 2, c: 345 }).toRawType()
|
||||
).toEqual(JSON.stringify({
|
||||
_set: { a: 1, b: 2, c: 345 }
|
||||
}));
|
||||
});
|
||||
});
|
||||
File diff suppressed because one or more lines are too long
@@ -1,326 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/* eslint-disable sort-keys */
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, U32 } from '../primitive';
|
||||
import { TEST_A } from './Struct.data';
|
||||
import { Enum, Struct, Vec } from '.';
|
||||
|
||||
describe('Struct', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('decoding', (): void => {
|
||||
const testDecode = (type: string, input: any): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const s = new Struct(registry, {
|
||||
foo: Text,
|
||||
bar: U32
|
||||
}, input);
|
||||
|
||||
expect([...s.keys()]).toEqual(['foo', 'bar']);
|
||||
expect(
|
||||
[...s.values()].map((v): string =>
|
||||
v.toString()
|
||||
)
|
||||
).toEqual(['bazzing', '69']);
|
||||
});
|
||||
|
||||
testDecode('array', ['bazzing', 69]);
|
||||
testDecode('hex', '0x1c62617a7a696e6745000000');
|
||||
testDecode('object', { foo: 'bazzing', bar: 69 });
|
||||
testDecode('Uint8Array', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0]));
|
||||
});
|
||||
|
||||
describe('encoding', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
const s = new Struct(registry, {
|
||||
foo: Text,
|
||||
bar: U32
|
||||
}, { foo: 'bazzing', bar: 69 });
|
||||
|
||||
expect(s[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', '0x1c62617a7a696e6745000000');
|
||||
testEncode('toJSON', { foo: 'bazzing', bar: 69 });
|
||||
testEncode('toU8a', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0]));
|
||||
testEncode('toString', '{"foo":"bazzing","bar":69}');
|
||||
});
|
||||
|
||||
it('decodes null/undefined/empty correctly (& equivalently)', (): void => {
|
||||
const Clazz = Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
});
|
||||
const expected = { txt: '', u32: '0' };
|
||||
|
||||
expect(new Clazz(registry, {}).toHuman()).toEqual(expected);
|
||||
expect(new Clazz(registry, null).toHuman()).toEqual(expected);
|
||||
expect(new Clazz(registry, undefined).toHuman()).toEqual(expected);
|
||||
});
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new Struct(
|
||||
registry,
|
||||
{ foo: Text },
|
||||
{ foo }
|
||||
)).get('foo')
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
it('decodes a more complicated type', (): void => {
|
||||
const s = new Struct(registry, {
|
||||
foo: Vec.with(Struct.with({
|
||||
bar: Text
|
||||
}))
|
||||
}, { foo: [{ bar: 1 }, { bar: 2 }] });
|
||||
|
||||
expect(s.toString()).toBe('{"foo":[{"bar":"1"},{"bar":"2"}]}');
|
||||
});
|
||||
|
||||
it('decodes a previously problematic input', (): void => {
|
||||
let data;
|
||||
|
||||
try {
|
||||
data = new Struct(registry, {
|
||||
a: 'u32',
|
||||
b: 'H256',
|
||||
c: 'H256',
|
||||
swap: Enum.with({
|
||||
A: 'u256',
|
||||
B: 'u256'
|
||||
}),
|
||||
d: Vec.with('u8'),
|
||||
e: 'u8'
|
||||
}, TEST_A);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
expect(data.get('d')).toHaveLength(50000);
|
||||
});
|
||||
|
||||
it('decodes from a Map input', (): void => {
|
||||
const s = new Struct(registry, {
|
||||
txt: Text,
|
||||
foo: U32,
|
||||
bar: U32
|
||||
}, new Map<string, unknown>([['a', 42], ['txt', 'fubar']]));
|
||||
|
||||
expect(s.toString()).toEqual('{"txt":"fubar","foo":0,"bar":0}');
|
||||
});
|
||||
|
||||
it('decodes from a snake_case input', (): void => {
|
||||
const input = new Struct(registry, {
|
||||
snakeCaseA: U32,
|
||||
snakeCaseB: Text,
|
||||
other: U32
|
||||
}, { snake_case_a: 42, snake_case_b: 'fubar', other: 69 } as any);
|
||||
|
||||
expect(input.toString()).toEqual('{"snakeCaseA":42,"snakeCaseB":"fubar","other":69}');
|
||||
});
|
||||
|
||||
it('throws when it cannot decode', (): void => {
|
||||
expect(
|
||||
(): Struct<any> => new (
|
||||
Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
})
|
||||
)(registry, 'ABC')
|
||||
).toThrowError(/Cannot decode value/);
|
||||
});
|
||||
|
||||
it('throws a sensical error on incorrect array values passed to structs', (): void => {
|
||||
expect(
|
||||
() => new Struct(registry, {
|
||||
_: 'Vec<u32>'
|
||||
}, [123, 456])
|
||||
).toThrow(/array to object with known keys/);
|
||||
});
|
||||
|
||||
it('provides a clean toString()', (): void => {
|
||||
expect(
|
||||
new (
|
||||
Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
})
|
||||
)(registry, { txt: 'foo', u32: 0x123456 }).toString()
|
||||
).toEqual('{"txt":"foo","u32":1193046}');
|
||||
});
|
||||
|
||||
it('provides a clean toString() (string types)', (): void => {
|
||||
expect(
|
||||
new (
|
||||
Struct.with({
|
||||
txt: 'Text',
|
||||
num: 'u32',
|
||||
cls: U32
|
||||
})
|
||||
)(registry, { txt: 'foo', num: 0x123456, cls: 123 }).toString()
|
||||
).toEqual('{"txt":"foo","num":1193046,"cls":123}');
|
||||
});
|
||||
|
||||
it('exposes the properties on the object', (): void => {
|
||||
const struct = new (
|
||||
Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
})
|
||||
)(registry, { txt: 'foo', u32: 0x123456 });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
||||
expect((struct as any).txt.toString()).toEqual('foo');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
||||
expect((struct as any).u32.toNumber()).toEqual(0x123456);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(
|
||||
new (
|
||||
Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
})
|
||||
)(registry, { foo: 'bazzing', bar: 69 }).encodedLength
|
||||
).toEqual(5);
|
||||
});
|
||||
|
||||
it('exposes the types', (): void => {
|
||||
expect(
|
||||
new Struct(registry, {
|
||||
foo: Text,
|
||||
bar: Text,
|
||||
baz: U32
|
||||
}, {
|
||||
foo: 'foo',
|
||||
bar: 'bar',
|
||||
baz: 3
|
||||
}).Type
|
||||
).toEqual({
|
||||
foo: 'Text',
|
||||
bar: 'Text',
|
||||
baz: 'u32'
|
||||
});
|
||||
});
|
||||
|
||||
it('gets the value at a particular index', (): void => {
|
||||
expect(
|
||||
new (
|
||||
Struct.with({
|
||||
txt: Text,
|
||||
u32: U32
|
||||
})
|
||||
)(registry, { txt: 'foo', u32: 1234 })
|
||||
.getAtIndex(1)
|
||||
.toString()
|
||||
).toEqual('1234');
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against other objects', (): void => {
|
||||
const test = {
|
||||
foo: 'foo',
|
||||
bar: 'bar',
|
||||
baz: 3
|
||||
};
|
||||
|
||||
expect(
|
||||
new Struct(registry, {
|
||||
foo: Text,
|
||||
bar: Text,
|
||||
baz: U32
|
||||
}, test).eq(test)
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('allows toString with large numbers', (): void => {
|
||||
// replicate https://github.com/polkadot-js/api/issues/640
|
||||
expect(
|
||||
new Struct(registry, {
|
||||
blockNumber: registry.createClass('Option<BlockNumber>')
|
||||
}, { blockNumber: '0x0000000010abcdef' }).toString()
|
||||
).toEqual('{"blockNumber":279694831}');
|
||||
});
|
||||
|
||||
it('generates sane toRawType', (): void => {
|
||||
expect(
|
||||
new Struct(registry, {
|
||||
accountId: 'AccountId',
|
||||
balanceCompact: registry.createClass('Compact<Balance>'),
|
||||
blockNumber: registry.createClass('BlockNumber'),
|
||||
compactNumber: registry.createClass('Compact<BlockNumber>'),
|
||||
optionNumber: registry.createClass('Option<BlockNumber>'),
|
||||
counter: U32,
|
||||
vector: Vec.with('AccountId')
|
||||
}).toRawType()
|
||||
).toEqual(JSON.stringify({
|
||||
accountId: 'AccountId',
|
||||
balanceCompact: 'Compact<Balance>', // Override in Uint
|
||||
blockNumber: 'BlockNumber',
|
||||
compactNumber: 'Compact<BlockNumber>',
|
||||
optionNumber: 'Option<BlockNumber>',
|
||||
counter: 'u32',
|
||||
vector: 'Vec<AccountId>'
|
||||
}));
|
||||
});
|
||||
|
||||
it('generates sane toRawType (via with)', (): void => {
|
||||
const Type = Struct.with({
|
||||
accountId: 'AccountId',
|
||||
balance: registry.createClass('Balance')
|
||||
});
|
||||
|
||||
expect(
|
||||
new Type(registry).toRawType()
|
||||
).toEqual(JSON.stringify({
|
||||
accountId: 'AccountId',
|
||||
balance: 'Balance' // Override in Uint
|
||||
}));
|
||||
});
|
||||
|
||||
describe('toU8a', (): void => {
|
||||
const def: Record<string, any> = {
|
||||
foo: 'Bytes',
|
||||
method: 'Bytes',
|
||||
bar: 'Option<u32>',
|
||||
baz: 'bool'
|
||||
};
|
||||
const val = {
|
||||
foo: '0x4269',
|
||||
method: '0x99',
|
||||
bar: 1,
|
||||
baz: true
|
||||
};
|
||||
|
||||
it('generates toU8a with undefined', (): void => {
|
||||
expect(
|
||||
new Struct(registry, def, val).toU8a()
|
||||
).toEqual(new Uint8Array([2 << 2, 0x42, 0x69, 1 << 2, 0x99, 1, 1, 0, 0, 0, 1]));
|
||||
});
|
||||
|
||||
it('generates toU8a with true', (): void => {
|
||||
expect(
|
||||
new Struct(registry, def, val).toU8a(true)
|
||||
).toEqual(new Uint8Array([0x42, 0x69, 0x99, 1, 0, 0, 0, 1]));
|
||||
});
|
||||
|
||||
it('generates toU8a with { method: true }', (): void => {
|
||||
expect(
|
||||
new Struct(registry, def, val).toU8a({ method: true })
|
||||
).toEqual(new Uint8Array([2 << 2, 0x42, 0x69, 0x99, 1, 1, 0, 0, 0, 1]));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,142 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AnyTupleValue, CodecTo } from '@polkadot/types-codec/types';
|
||||
import type { VoteThreshold } from '../interfaces/elections';
|
||||
import type { BlockNumber } from '../interfaces/runtime';
|
||||
|
||||
import rpcMetadata from '@polkadot/types-support/metadata/static-substrate';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Metadata } from '../metadata';
|
||||
import { Text, U32, U128 } from '../primitive';
|
||||
import { Tuple } from '.';
|
||||
|
||||
describe('Tuple', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
let tuple: Tuple;
|
||||
|
||||
beforeEach((): void => {
|
||||
tuple = new Tuple(
|
||||
registry,
|
||||
[Text, U32],
|
||||
['bazzing', 69]
|
||||
);
|
||||
});
|
||||
|
||||
describe('decoding', (): void => {
|
||||
const testDecode = (type: string, input: AnyTupleValue): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
const t = new Tuple(registry, [
|
||||
Text,
|
||||
U32
|
||||
], input);
|
||||
|
||||
expect(
|
||||
t.toJSON()
|
||||
).toEqual(['bazzing', 69]);
|
||||
});
|
||||
|
||||
testDecode('array', ['bazzing', 69]);
|
||||
testDecode('hex', '0x1c62617a7a696e6745000000');
|
||||
testDecode('Uint8Array', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0]));
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new Tuple(registry, [Text], [foo]))[0]
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
it('decodes properly from complex types', (): void => {
|
||||
const INPUT = '0xcc0200000000';
|
||||
const test = registry.createType('(u32, [u32; 0], u16)', INPUT);
|
||||
|
||||
expect(test.encodedLength).toEqual(4 + 0 + 2);
|
||||
expect(test.toHex()).toEqual(INPUT);
|
||||
});
|
||||
});
|
||||
|
||||
describe('encoding', (): void => {
|
||||
const testEncode = (to: CodecTo | 'toArray', expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
expect(tuple[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', '0x1c62617a7a696e6745000000');
|
||||
testEncode('toJSON', ['bazzing', 69]);
|
||||
testEncode('toU8a', Uint8Array.from([28, 98, 97, 122, 122, 105, 110, 103, 69, 0, 0, 0]));
|
||||
testEncode('toString', '["bazzing",69]');
|
||||
});
|
||||
|
||||
it('creates from string types', (): void => {
|
||||
expect(
|
||||
new Tuple(
|
||||
registry,
|
||||
['Text', 'u32', U32],
|
||||
['foo', 69, 42]
|
||||
).toString()
|
||||
).toEqual('["foo",69,42]');
|
||||
});
|
||||
|
||||
it('creates properly via actual hex string', (): void => {
|
||||
const metadata = new Metadata(registry, rpcMetadata);
|
||||
|
||||
registry.setMetadata(metadata);
|
||||
|
||||
const test = new (Tuple.with([
|
||||
registry.createClass('BlockNumber'), registry.createClass('VoteThreshold')
|
||||
]
|
||||
))(registry, '0x6219000001');
|
||||
|
||||
expect((test[0] as BlockNumber).toNumber()).toEqual(6498);
|
||||
expect((test[1] as VoteThreshold).toNumber()).toEqual(1);
|
||||
});
|
||||
|
||||
it('exposes the Types', (): void => {
|
||||
expect(tuple.Types).toEqual(['Text', 'u32']);
|
||||
});
|
||||
|
||||
it('exposes the Types (object creation)', (): void => {
|
||||
const test = new Tuple(registry, {
|
||||
BlockNumber: registry.createClass('BlockNumber'),
|
||||
VoteThreshold: registry.createClass('VoteThreshold')
|
||||
}, []);
|
||||
|
||||
expect(test.Types).toEqual(['BlockNumber', 'VoteThreshold']);
|
||||
});
|
||||
|
||||
it('exposes filter', (): void => {
|
||||
expect(tuple.filter((v): boolean => v.toJSON() === 69)).toEqual([new U32(registry, 69)]);
|
||||
});
|
||||
|
||||
it('exposes map', (): void => {
|
||||
expect(tuple.map((v): string => v.toString())).toEqual(['bazzing', '69']);
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against inputs', (): void => {
|
||||
expect(tuple.eq(['bazzing', 69])).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against inputs (mismatch)', (): void => {
|
||||
expect(tuple.eq(['bazzing', 72])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toRawType', (): void => {
|
||||
it('generates sane value with array types', (): void => {
|
||||
expect(
|
||||
new Tuple(registry, [U128, registry.createClass('BlockNumber')]).toRawType()
|
||||
).toEqual('(u128,BlockNumber)');
|
||||
});
|
||||
|
||||
it('generates sane value with object types', (): void => {
|
||||
expect(
|
||||
// eslint-disable-next-line sort-keys
|
||||
new Tuple(registry, { number: U128, blockNumber: registry.createClass('BlockNumber') }).toRawType()
|
||||
).toEqual('(u128,BlockNumber)');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { U8aFixed } from '.';
|
||||
|
||||
describe('U8aFixed', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('construction', (): void => {
|
||||
it('allows empty values', (): void => {
|
||||
expect(
|
||||
new U8aFixed(registry).toHex()
|
||||
).toEqual('0x0000000000000000000000000000000000000000000000000000000000000000');
|
||||
});
|
||||
|
||||
it('allows construction via with', (): void => {
|
||||
expect(
|
||||
new (U8aFixed.with(64))(registry).bitLength()
|
||||
).toEqual(64);
|
||||
});
|
||||
|
||||
it('constructs from hex', (): void => {
|
||||
expect(
|
||||
new (U8aFixed.with(32))(registry, '0x01020304').toU8a()
|
||||
).toEqual(
|
||||
new Uint8Array([0x01, 0x02, 0x03, 0x04])
|
||||
);
|
||||
});
|
||||
|
||||
it('constructs from number[]', (): void => {
|
||||
expect(
|
||||
new (U8aFixed.with(32))(registry, [0x02, 0x03, 0x00, 0x00]).toU8a()
|
||||
).toEqual(
|
||||
new Uint8Array([0x02, 0x03, 0x00, 0x00])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
let u8a: U8aFixed;
|
||||
|
||||
beforeEach((): void => {
|
||||
u8a = new U8aFixed(registry, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 32);
|
||||
});
|
||||
|
||||
it('limits the length', (): void => {
|
||||
expect(u8a.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('exposes the correct bitLength', (): void => {
|
||||
expect(u8a.bitLength()).toEqual(32);
|
||||
});
|
||||
|
||||
it('allows wrapping of a pre-existing instance', (): void => {
|
||||
expect(
|
||||
u8a.toU8a()
|
||||
).toEqual(new Uint8Array([1, 2, 3, 4]));
|
||||
});
|
||||
|
||||
it('hash a sane toRawType', (): void => {
|
||||
expect(u8a.toRawType()).toEqual('[u8;4]');
|
||||
});
|
||||
});
|
||||
|
||||
describe('static with', (): void => {
|
||||
it('allows default toRawType', (): void => {
|
||||
expect(
|
||||
new (U8aFixed.with(64))(registry).toRawType()
|
||||
).toEqual('[u8;8]');
|
||||
});
|
||||
|
||||
it('allows toRawType override', (): void => {
|
||||
expect(
|
||||
new (U8aFixed.with(64, 'SomethingElse'))(registry).toRawType()
|
||||
).toEqual('SomethingElse');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,163 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { BN, BN_TWO, isBn } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { UInt } from '.';
|
||||
|
||||
describe('UInt', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('decodes an empty Uint8array correctly', (): void => {
|
||||
expect(
|
||||
new UInt(registry, new Uint8Array()).toNumber()
|
||||
).toEqual(0);
|
||||
});
|
||||
|
||||
it('still has the BN interfaces', (): void => {
|
||||
expect([
|
||||
new UInt(registry, 32).mul(BN_TWO).toNumber(),
|
||||
new UInt(registry, 64).divn(2).toNumber()
|
||||
]).toEqual([64, 32]);
|
||||
});
|
||||
|
||||
it('is a BN instance', (): void => {
|
||||
const test = new UInt(registry, 16);
|
||||
|
||||
expect(isBn(test)).toBe(true);
|
||||
expect(BN.isBN(test)).toBe(true);
|
||||
expect(test instanceof BN).toBe(true);
|
||||
});
|
||||
|
||||
// e.g. headers
|
||||
it('decodes hex that are not multiples of 2', (): void => {
|
||||
expect(new UInt(registry, '0x123').toNumber()).toEqual(0x123);
|
||||
expect(new UInt(registry, '0x0123').toNumber()).toEqual(0x123);
|
||||
});
|
||||
|
||||
it('fails on a number that is too large for the bits specified', (): void => {
|
||||
expect(
|
||||
(): UInt => new UInt(registry, '12345678901234567890123456789012345678901234567890', 32)
|
||||
).toThrow('u32: Input too large. Found input with 164 bits, expected 32');
|
||||
});
|
||||
|
||||
it('fails on negative numbers', (): void => {
|
||||
expect(
|
||||
(): UInt => new UInt(registry, -123, 32)
|
||||
).toThrow('u32: Negative number passed to unsigned type');
|
||||
});
|
||||
|
||||
it('allows for construction via BigInt', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 123456789123456789123456789n, 128).toHuman()
|
||||
).toEqual('123,456,789,123,456,789,123,456,789');
|
||||
});
|
||||
|
||||
it('provides a toBigInt interface', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 9876543210123456789n).toBigInt()
|
||||
).toEqual(9876543210123456789n);
|
||||
});
|
||||
|
||||
it('provides a toBn interface', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 987).toBn().toNumber()
|
||||
).toEqual(987);
|
||||
});
|
||||
|
||||
it('provides a toNumber interface', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 4567).toNumber()
|
||||
).toEqual(4567);
|
||||
});
|
||||
|
||||
it('has a working toBigInt', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 4567).toBigInt() + BigInt(1)
|
||||
).toEqual(BigInt(4568));
|
||||
});
|
||||
|
||||
it('converts to Little Endian from the provided value', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 1234567).toU8a()
|
||||
).toEqual(new Uint8Array([135, 214, 18, 0, 0, 0, 0, 0]));
|
||||
});
|
||||
|
||||
it('converts to Little Endian from the provided value (bitLength)', (): void => {
|
||||
expect(
|
||||
new UInt(registry, 1234567, 32).toU8a()
|
||||
).toEqual(new Uint8Array([135, 214, 18, 0]));
|
||||
});
|
||||
|
||||
it('converts to hex/string', (): void => {
|
||||
const u = new UInt(registry, '0x12', 16);
|
||||
|
||||
expect(u.toHex()).toEqual('0x0012');
|
||||
expect(u.toString()).toEqual('18');
|
||||
});
|
||||
|
||||
it('converts to equivalents', (): void => {
|
||||
const a = new UInt(registry, '123');
|
||||
|
||||
expect(
|
||||
new UInt(registry, a).toNumber()
|
||||
).toEqual(123);
|
||||
});
|
||||
|
||||
it('converts to JSON representation based on size', (): void => {
|
||||
expect(new UInt(registry, '0x12345678', 32).toJSON()).toEqual(0x12345678);
|
||||
expect(new UInt(registry, '0x1234567890', 64).toJSON()).toEqual(78187493520); // '0x0000001234567890');
|
||||
expect(new UInt(registry, '0x1234567890abcdef', 64).toJSON()).toEqual('0x1234567890abcdef');
|
||||
});
|
||||
|
||||
describe('eq', (): void => {
|
||||
const test = new UInt(registry, 12345);
|
||||
|
||||
it('compares against other BN values', (): void => {
|
||||
expect(test.eq(new BN(12345))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against other number values', (): void => {
|
||||
expect(test.eq(12345)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against hex values', (): void => {
|
||||
expect(test.eq('0x3039')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isMax()', (): void => {
|
||||
it('is false where not full', (): void => {
|
||||
expect(new UInt(registry, '0x1234', 32).isMax()).toEqual(false);
|
||||
expect(new UInt(registry, '0xffffff', 32).isMax()).toEqual(false);
|
||||
expect(new UInt(registry, '0x12345678', 32).isMax()).toEqual(false);
|
||||
expect(new UInt(registry, '0xfffffff0', 32).isMax()).toEqual(false);
|
||||
});
|
||||
|
||||
it('is true when full', (): void => {
|
||||
expect(new UInt(registry, '0xffffffff', 32).isMax()).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('static with', (): void => {
|
||||
it('allows default toRawType', (): void => {
|
||||
expect(
|
||||
new (UInt.with(64))(registry).toRawType()
|
||||
).toEqual('u64');
|
||||
});
|
||||
|
||||
it('allows toRawType override', (): void => {
|
||||
expect(
|
||||
new (UInt.with(64, 'SomethingElse'))(registry).toRawType()
|
||||
).toEqual('SomethingElse');
|
||||
});
|
||||
|
||||
it('has proper toHuman() for PerMill/PerBill/Percent/Balance', (): void => {
|
||||
expect(registry.createType('Perbill', 12_340_000).toHuman()).toEqual('1.23%');
|
||||
expect(registry.createType('Percent', 12).toHuman()).toEqual('12.00%');
|
||||
expect(registry.createType('Permill', 16_900).toHuman()).toEqual('1.69%');
|
||||
expect(registry.createType('Balance', '123456789012345').toHuman()).toEqual('123.4567 Unit');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,183 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PropIndex } from '../interfaces/democracy';
|
||||
import type { Codec, CodecTo, ITuple } from '../types';
|
||||
|
||||
import rpcMetadata from '@polkadot/types-support/metadata/static-substrate';
|
||||
import { randomAsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { createTypeUnsafe, TypeRegistry } from '../create';
|
||||
import { GenericAccountId as AccountId } from '../generic';
|
||||
import { Metadata } from '../metadata';
|
||||
import { Text } from '../primitive';
|
||||
import { Vec } from '.';
|
||||
|
||||
const registry = new TypeRegistry();
|
||||
const metadata = new Metadata(registry, rpcMetadata);
|
||||
|
||||
registry.setMetadata(metadata);
|
||||
|
||||
describe('Vec', (): void => {
|
||||
let vector: Vec<Codec>;
|
||||
|
||||
beforeEach((): void => {
|
||||
vector = new Vec(registry, Text, ['1', '23', '345', '4567', new Text(registry, '56789')]);
|
||||
});
|
||||
|
||||
it('wraps a sequence of values', (): void => {
|
||||
expect(vector.length).toEqual(5); // eslint-disable-line
|
||||
});
|
||||
|
||||
it('has a sane representation for toString', (): void => {
|
||||
expect(vector.toString()).toEqual('[1, 23, 345, 4567, 56789]');
|
||||
});
|
||||
|
||||
it('encodes with length prefix', (): void => {
|
||||
expect(vector.toU8a()).toEqual(new Uint8Array([
|
||||
5 << 2,
|
||||
1 << 2, 49,
|
||||
2 << 2, 50, 51,
|
||||
3 << 2, 51, 52, 53,
|
||||
4 << 2, 52, 53, 54, 55,
|
||||
5 << 2, 53, 54, 55, 56, 57
|
||||
]));
|
||||
});
|
||||
|
||||
it('allows construction via JSON', (): void => {
|
||||
expect(
|
||||
new Vec(registry, Text, ['6', '7']).toJSON()
|
||||
).toEqual(['6', '7']);
|
||||
});
|
||||
|
||||
it('allows construction via JSON (string type)', (): void => {
|
||||
expect(
|
||||
new Vec(registry, 'u32', ['6', '7']).toJSON()
|
||||
).toEqual([6, 7]);
|
||||
});
|
||||
|
||||
it('exposes the type', (): void => {
|
||||
expect(vector.Type).toEqual('Text');
|
||||
});
|
||||
|
||||
it('decodes reusing instantiated inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new Vec(registry, Text, [foo]))[0]
|
||||
).toBe(foo);
|
||||
});
|
||||
|
||||
it('decodes a complex type via construction', (): void => {
|
||||
const test = createTypeUnsafe<Vec<ITuple<[PropIndex, AccountId]>>>(registry, 'Vec<(PropIndex, AccountId)>', [new Uint8Array([
|
||||
4, 10, 0, 0, 0, 209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79
|
||||
])]);
|
||||
|
||||
expect(test[0][0].toNumber()).toEqual(10);
|
||||
expect(test[0][1].toString()).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua');
|
||||
});
|
||||
|
||||
it('decodes a complex type via construction', (): void => {
|
||||
const INPUT = '0x08cc0200000000ce0200000001';
|
||||
const test = createTypeUnsafe<Vec<Codec>>(registry, 'Vec<(u32, [u32; 0], u16)>', [INPUT]);
|
||||
|
||||
expect(test).toHaveLength(2);
|
||||
expect(test.toHex()).toEqual(INPUT);
|
||||
});
|
||||
|
||||
describe('vector-like functions', (): void => {
|
||||
it('allows retrieval of a specific item', (): void => {
|
||||
expect(
|
||||
vector[2].toString()
|
||||
).toEqual('345');
|
||||
});
|
||||
|
||||
it('exposes a working forEach', (): void => {
|
||||
const result: { [index: number]: string } = {};
|
||||
|
||||
vector.forEach((e, i): void => {
|
||||
result[i] = e.toString();
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
0: '1',
|
||||
1: '23',
|
||||
2: '345',
|
||||
3: '4567',
|
||||
4: '56789'
|
||||
});
|
||||
});
|
||||
|
||||
it('exposes a working concat', (): void => {
|
||||
expect(
|
||||
vector.concat(new Vec(registry, Text, ['987', '654'])).toString()
|
||||
).toEqual('1,23,345,4567,56789,987,654');
|
||||
});
|
||||
|
||||
it('exposes a working filter', (): void => {
|
||||
expect(
|
||||
vector.filter((e, i): boolean => i >= 3).toString()
|
||||
).toEqual('4567,56789');
|
||||
});
|
||||
|
||||
it('exposes a working map', (): void => {
|
||||
expect(
|
||||
vector.map((e): string => e.toString().substr(0, 1))
|
||||
).toEqual(['1', '2', '3', '4', '5']);
|
||||
});
|
||||
|
||||
it('exposes a working reduce', (): void => {
|
||||
expect(
|
||||
vector.reduce((r, e): string => `${r}${e.toString()}`, '')
|
||||
).toEqual('123345456756789');
|
||||
});
|
||||
|
||||
it('exposes a working indexOf', (): void => {
|
||||
expect(vector.indexOf('1')).toEqual(0);
|
||||
expect(vector.indexOf(new Text(registry, '23'))).toEqual(1);
|
||||
expect(vector.indexOf('0')).toEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('encode', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: any): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
expect(vector[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', '0x1404310832330c3334351034353637143536373839');
|
||||
testEncode('toJSON', ['1', '23', '345', '4567', '56789']);
|
||||
testEncode('toString', '[1, 23, 345, 4567, 56789]');
|
||||
testEncode('toU8a', Uint8Array.from([20, 4, 49, 8, 50, 51, 12, 51, 52, 53, 16, 52, 53, 54, 55, 20, 53, 54, 55, 56, 57]));
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
const vec = new Vec(registry, Text, ['123', '456']);
|
||||
|
||||
it('compares against codec types', (): void => {
|
||||
expect(vec.eq([new Text(registry, '123'), new Text(registry, '456')])).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against codec + primitive types', (): void => {
|
||||
expect(vec.eq(['123', new Text(registry, '456')])).toBe(true);
|
||||
});
|
||||
|
||||
it('finds the index of an value', (): void => {
|
||||
const myId = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY';
|
||||
const vec = new Vec(registry, AccountId, [
|
||||
'5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw', '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty', '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'
|
||||
]);
|
||||
|
||||
expect(vec.indexOf(myId)).toEqual(2);
|
||||
});
|
||||
|
||||
it('allows a slice operator', (): void => {
|
||||
const vec = registry.createType('Vec<AccountId>', [
|
||||
randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a(), randomAsU8a()
|
||||
]);
|
||||
|
||||
expect(vec).toHaveLength(10);
|
||||
expect(vec.slice(2, 7)).toHaveLength(5);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, u16 } from '../primitive';
|
||||
import { VecFixed } from '.';
|
||||
|
||||
describe('VecFixed', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('construction', (): void => {
|
||||
it('constructs via empty', (): void => {
|
||||
expect(new VecFixed(registry, Text, 2).toHex()).toEqual('0x0000');
|
||||
});
|
||||
|
||||
it('constructs via Uint8Array', (): void => {
|
||||
expect(new VecFixed(registry, Text, 2, new Uint8Array([0x00, 0x04, 0x31])).toHex()).toEqual('0x000431');
|
||||
});
|
||||
|
||||
it('constructs via hex', (): void => {
|
||||
expect(new VecFixed(registry, u16, 2, '0x12345678').toHex()).toEqual('0x12345678');
|
||||
});
|
||||
|
||||
it('decodes reusing instance inputs', (): void => {
|
||||
const foo = new Text(registry, 'bar');
|
||||
|
||||
expect(
|
||||
(new VecFixed(registry, Text, 1, [foo]))[0]
|
||||
).toBe(foo);
|
||||
});
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
let test: VecFixed<Text>;
|
||||
|
||||
beforeEach((): void => {
|
||||
test = new (VecFixed.with(Text, 5))(registry, ['1', '2', '3', undefined, '5']);
|
||||
});
|
||||
|
||||
it('has a sane string types', (): void => {
|
||||
expect(test.toRawType()).toEqual('[Text;5]');
|
||||
expect(test.Type).toEqual('Text');
|
||||
});
|
||||
|
||||
it('has a correct toHex', (): void => {
|
||||
// each entry length 1 << 2, char as hex (0x31 === `1`), one empty
|
||||
expect(test.toHex()).toEqual('0x043104320433000435');
|
||||
});
|
||||
|
||||
it('has empty Uint8Array when length is 0', (): void => {
|
||||
const test = new (VecFixed.with(Text, 0))(registry);
|
||||
|
||||
expect(test.encodedLength).toEqual(0);
|
||||
expect(test.toU8a()).toEqual(new Uint8Array([]));
|
||||
});
|
||||
|
||||
it('has equivalent to 1 Uint8Array when length is 1', (): void => {
|
||||
const test = new (VecFixed.with(Text, 1))(registry, ['hello']);
|
||||
|
||||
expect(test.encodedLength).toEqual(1 + 5);
|
||||
expect(test.toU8a()).toEqual(new Uint8Array([20, 104, 101, 108, 108, 111]));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { WrapperOpaque } from '.';
|
||||
|
||||
describe('WrapperOpaque', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
const u8au32 = new Uint8Array([4 << 2, 135, 214, 18, 0]);
|
||||
|
||||
it('u8a encodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', 1234567).toU8a()
|
||||
).toEqual(u8au32);
|
||||
});
|
||||
|
||||
it('u8a decodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', u8au32).toU8a()
|
||||
).toEqual(u8au32);
|
||||
});
|
||||
|
||||
it('hex encodes a wrapped u32 correctly', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', '0x12345678').toHex()
|
||||
).toEqual('0x12345678');
|
||||
});
|
||||
|
||||
it('has the correct unwrap', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32', '0x12345678').unwrap().toHex()
|
||||
).toEqual('0x12345678');
|
||||
});
|
||||
|
||||
it('has the correct toRawType', (): void => {
|
||||
expect(
|
||||
new WrapperOpaque(registry, 'u32').toRawType()
|
||||
).toEqual('WrapperOpaque<u32>');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec, CodecClass, CodecRegistry } from '@polkadot/types-codec/types';
|
||||
import type { DetectCodec } from '../types';
|
||||
|
||||
import { createClassUnsafe } from '@polkadot/types-create';
|
||||
|
||||
export function createClass<T extends Codec = Codec, K extends string = string> (registry: CodecRegistry, type: K): CodecClass<DetectCodec<T, K>> {
|
||||
return createClassUnsafe(registry, type);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec, CodecRegistry } from '@polkadot/types-codec/types';
|
||||
import type { DetectCodec } from '../types';
|
||||
|
||||
import { createTypeUnsafe } from '@polkadot/types-create';
|
||||
|
||||
/**
|
||||
* Create an instance of a `type` with a given `params`.
|
||||
* @param type - A recognizable string representing the type to create an
|
||||
* instance from
|
||||
* @param params - The value to instantiate the type with
|
||||
*/
|
||||
export function createType<T extends Codec = Codec, K extends string = string> (registry: CodecRegistry, type: K, ...params: unknown[]): DetectCodec<T, K> {
|
||||
return createTypeUnsafe(registry, type, params);
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeDefInfo } from '@polkadot/types-create';
|
||||
|
||||
import { TypeRegistry } from './registry';
|
||||
import { encodeTypeDef } from '.';
|
||||
|
||||
describe('encodeTypeDef', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('correctly encodes a complex struct', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'c',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
name: 'd',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}))
|
||||
).toEqual({
|
||||
a: 'u32',
|
||||
b: '{"c":"u32","d":"Vec<u32>"}'
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly encodes a complex struct (named)', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'c',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
displayName: 'Something',
|
||||
info: TypeDefInfo.Vec,
|
||||
name: 'd',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}))
|
||||
).toEqual({
|
||||
a: 'u32',
|
||||
b: '{"c":"u32","d":"Something"}'
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly encodes a complex enum', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'c',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
name: 'd',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Enum,
|
||||
name: 'f',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'g',
|
||||
type: 'Null'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'h',
|
||||
type: 'Null'
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}))
|
||||
).toEqual({
|
||||
_enum: {
|
||||
a: 'u32',
|
||||
b: '{"c":"u32","d":"Vec<u32>"}',
|
||||
f: '{"_enum":["g","h"]}'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly encodes a complex enum (named)', (): void => {
|
||||
expect(
|
||||
JSON.parse(encodeTypeDef(registry, {
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
displayName: 'Something',
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'c',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
name: 'd',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
},
|
||||
{
|
||||
displayName: 'Option',
|
||||
info: TypeDefInfo.Option,
|
||||
name: 'e',
|
||||
sub: {
|
||||
displayName: 'Result',
|
||||
info: TypeDefInfo.Result,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Null,
|
||||
type: ''
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
},
|
||||
type: ''
|
||||
}
|
||||
],
|
||||
type: ''
|
||||
}))
|
||||
).toEqual({
|
||||
_enum: {
|
||||
a: 'u32',
|
||||
b: 'Something',
|
||||
e: 'Option<Result<Null, u32>>'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,534 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeDefInfo } from '@polkadot/types-create';
|
||||
|
||||
import { getTypeDef, TypeRegistry } from '.';
|
||||
|
||||
describe('getTypeDef', (): void => {
|
||||
it('maps empty tuples to empty tuple', (): void => {
|
||||
expect(
|
||||
getTypeDef('()')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [],
|
||||
type: '()'
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a BTreeMap<u32, Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('BTreeMap<u32, Text>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.BTreeMap,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
}
|
||||
],
|
||||
type: 'BTreeMap<u32,Text>'
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a BTreeSet<Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('BTreeSet<Text>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.BTreeSet,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
},
|
||||
type: 'BTreeSet<Text>'
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a Result<u32, Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('Result<u32, Text>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Result,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
}
|
||||
],
|
||||
type: 'Result<u32,Text>'
|
||||
});
|
||||
});
|
||||
|
||||
it('properly decodes a Result<Result<(), u32>, Text>', (): void => {
|
||||
expect(
|
||||
getTypeDef('Result<Result<Null,u32>,Text>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Result,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Result,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Null'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
}
|
||||
],
|
||||
type: 'Result<Null,u32>'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
}
|
||||
],
|
||||
type: 'Result<Result<Null,u32>,Text>'
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a type structure', (): void => {
|
||||
expect(
|
||||
getTypeDef('(u32, Compact<u32>, Vec<u64>, Option<u128>, (Text,Vec<(Bool,u128)>))')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Compact,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
type: 'Compact<u32>'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
},
|
||||
type: 'Vec<u64>'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Option,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
},
|
||||
type: 'Option<u128>'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Bool'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
],
|
||||
type: '(Bool,u128)'
|
||||
},
|
||||
type: 'Vec<(Bool,u128)>'
|
||||
}
|
||||
],
|
||||
type: '(Text,Vec<(Bool,u128)>)'
|
||||
}
|
||||
],
|
||||
type: '(u32,Compact<u32>,Vec<u64>,Option<u128>,(Text,Vec<(Bool,u128)>))'
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a type structure (sanitized)', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<(Box<PropIndex>, Proposal,Lookup::Target)>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'PropIndex'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Proposal'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'LookupTarget'
|
||||
}
|
||||
],
|
||||
type: '(PropIndex,Proposal,LookupTarget)'
|
||||
},
|
||||
type: 'Vec<(PropIndex,Proposal,LookupTarget)>'
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a type structure (actual)', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<(PropIndex, Proposal, AccountId)>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'PropIndex'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Proposal'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'AccountId'
|
||||
}
|
||||
],
|
||||
type: '(PropIndex,Proposal,AccountId)'
|
||||
},
|
||||
type: 'Vec<(PropIndex,Proposal,AccountId)>'
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an actual Struct', (): void => {
|
||||
expect(
|
||||
getTypeDef('{"balance":"Balance","account_id":"AccountId","log":"(u64, Signature)"}')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'balance',
|
||||
type: 'Balance'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'account_id',
|
||||
type: 'AccountId'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'log',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Signature'
|
||||
}
|
||||
],
|
||||
type: '(u64,Signature)'
|
||||
}
|
||||
],
|
||||
type: '{"balance":"Balance","account_id":"AccountId","log":"(u64,Signature)"}'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a nested fixed vec', (): void => {
|
||||
expect(
|
||||
getTypeDef('[[[bool; 3]; 6]; 9]')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 9,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 6,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 3,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
},
|
||||
type: '[bool;3]'
|
||||
},
|
||||
type: '[[bool;3];6]'
|
||||
},
|
||||
type: '[[[bool;3];6];9]'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a nested fixed vec (named)', (): void => {
|
||||
expect(
|
||||
getTypeDef('[[bool; 6]; 3; MyType]')
|
||||
).toEqual({
|
||||
displayName: 'MyType',
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 3,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 6,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
},
|
||||
type: '[bool;6]'
|
||||
},
|
||||
type: '[[bool;6];3;MyType]'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a nested tuple', (): void => {
|
||||
expect(
|
||||
getTypeDef('((u32, u64), u128)')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u64'
|
||||
}
|
||||
],
|
||||
type: '(u32,u64)'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u128'
|
||||
}
|
||||
],
|
||||
type: '((u32,u64),u128)'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a nested enum with tuple/struct', (): void => {
|
||||
expect(
|
||||
getTypeDef(JSON.stringify({
|
||||
_enum: {
|
||||
A: 'u32',
|
||||
B: '(u32, bool)',
|
||||
C: {
|
||||
d: 'AccountId',
|
||||
e: 'Balance'
|
||||
}
|
||||
}
|
||||
}))
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Enum,
|
||||
sub: [
|
||||
{
|
||||
index: 0,
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'A',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
index: 1,
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'B',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
}
|
||||
],
|
||||
type: '(u32,bool)'
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'C',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'd',
|
||||
type: 'AccountId'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'e',
|
||||
type: 'Balance'
|
||||
}
|
||||
],
|
||||
type: '{"d":"AccountId","e":"Balance"}'
|
||||
}
|
||||
],
|
||||
type: '{"_enum":{"A":"u32","B":"(u32,bool)","C":{"d":"AccountId","e":"Balance"}}}'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a nested struct with struct/tuple', (): void => {
|
||||
expect(
|
||||
getTypeDef(JSON.stringify({
|
||||
a: 'u32',
|
||||
b: '(u32, bool)',
|
||||
c: {
|
||||
d: 'AccountId',
|
||||
e: 'Balance'
|
||||
}
|
||||
}))
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
}
|
||||
],
|
||||
type: '(u32,bool)'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Struct,
|
||||
name: 'c',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'd',
|
||||
type: 'AccountId'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'e',
|
||||
type: 'Balance'
|
||||
}
|
||||
],
|
||||
type: '{"d":"AccountId","e":"Balance"}'
|
||||
}
|
||||
],
|
||||
type: '{"a":"u32","b":"(u32,bool)","c":{"d":"AccountId","e":"Balance"}}'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a Vec with nested fixed', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<[[[bool; 3]; 6]; 9]>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 9,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 6,
|
||||
sub: {
|
||||
info: TypeDefInfo.VecFixed,
|
||||
length: 3,
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
},
|
||||
type: '[bool;3]'
|
||||
},
|
||||
type: '[[bool;3];6]'
|
||||
},
|
||||
type: '[[[bool;3];6];9]'
|
||||
},
|
||||
type: 'Vec<[[[bool;3];6];9]>'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a Vec with nested struct', (): void => {
|
||||
expect(
|
||||
getTypeDef('Vec<{ "a": "u32", "b": "(u32, bool)" }>')
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Vec,
|
||||
sub: {
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
name: 'a',
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Tuple,
|
||||
name: 'b',
|
||||
sub: [
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'u32'
|
||||
},
|
||||
{
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'bool'
|
||||
}
|
||||
],
|
||||
type: '(u32,bool)'
|
||||
}
|
||||
],
|
||||
type: '{"a":"u32","b":"(u32,bool)"}'
|
||||
},
|
||||
type: 'Vec<{"a":"u32","b":"(u32,bool)"}>'
|
||||
});
|
||||
});
|
||||
|
||||
it('creates recursive structures', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
registry.register({
|
||||
Recursive: {
|
||||
data: 'Vec<Recursive>'
|
||||
}
|
||||
});
|
||||
|
||||
const raw = registry.createType('Recursive').toRawType();
|
||||
|
||||
expect(
|
||||
getTypeDef(raw)
|
||||
).toEqual({
|
||||
info: TypeDefInfo.Struct,
|
||||
sub: [{
|
||||
info: TypeDefInfo.Vec,
|
||||
name: 'data',
|
||||
sub: {
|
||||
info: TypeDefInfo.Plain,
|
||||
type: 'Recursive'
|
||||
},
|
||||
type: 'Vec<Recursive>'
|
||||
}],
|
||||
type: '{"data":"Vec<Recursive>"}'
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,26 +1,9 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Codec, CodecClass, CodecRegistry } from '@polkadot/types-codec/types';
|
||||
import type { DetectCodec } from '../types';
|
||||
|
||||
import { createClassUnsafe, createTypeUnsafe } from '@polkadot/types-create';
|
||||
|
||||
export * from '@polkadot/types-create';
|
||||
|
||||
export * from './createClass';
|
||||
export * from './createType';
|
||||
export * from './lazy';
|
||||
export * from './registry';
|
||||
|
||||
export function createClass<T extends Codec = Codec, K extends string = string> (registry: CodecRegistry, type: K): CodecClass<DetectCodec<T, K>> {
|
||||
return createClassUnsafe(registry, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of a `type` with a given `params`.
|
||||
* @param type - A recognizable string representing the type to create an
|
||||
* instance from
|
||||
* @param params - The value to instantiate the type with
|
||||
*/
|
||||
export function createType<T extends Codec = Codec, K extends string = string> (registry: CodecRegistry, type: K, ...params: unknown[]): DetectCodec<T, K> {
|
||||
return createTypeUnsafe(registry, type, params);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
|
||||
import type { Codec, CodecClass } from '@polkadot/types-codec/types';
|
||||
|
||||
import { DoNotConstruct, Struct } from '@polkadot/types-codec';
|
||||
import { DoNotConstruct, Struct, Text, U32 } from '@polkadot/types-codec';
|
||||
import { isChildClass, u8aToU8a } from '@polkadot/util';
|
||||
import { keccakAsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { Text, U32 } from '../primitive';
|
||||
import { TypeRegistry } from '.';
|
||||
|
||||
describe('TypeRegistry', (): void => {
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { typeSplit } from '.';
|
||||
|
||||
describe('typeSplit', (): void => {
|
||||
it('splits simple types into an array', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, u32, u64')
|
||||
).toEqual(['Text', 'u32', 'u64']);
|
||||
});
|
||||
|
||||
it('splits nested combinations', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32), Vec<u64>')
|
||||
).toEqual(['Text', '(u32)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<u64>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<u64>']);
|
||||
});
|
||||
|
||||
it('keeps nested vector tuples together', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, u128), Vec<(u64, u32)>')
|
||||
).toEqual(['Text', '(u32, u128)', 'Vec<(u64, u32)>']);
|
||||
});
|
||||
|
||||
it('allows for deep nesting', (): void => {
|
||||
expect(
|
||||
typeSplit('Text, (u32, (u128, u8)), Vec<(u64, (u32, u32))>')
|
||||
).toEqual(['Text', '(u32, (u128, u8))', 'Vec<(u64, (u32, u32))>']);
|
||||
});
|
||||
|
||||
it('checks for unclosed vec', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, Vec<u64')
|
||||
).toThrow(/Invalid definition/);
|
||||
});
|
||||
|
||||
it('checks for unclosed tuple', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, (u64, u32')
|
||||
).toThrow(/Invalid definition/);
|
||||
});
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { hexToU8a } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { BitVec } from './';
|
||||
|
||||
// form Inclusion BitVec<lsb0, u8>
|
||||
const TESTS = ['0x00', '0x0817', '0x0837', '0x087b', '0x0c33'];
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('BitVec', (): void => {
|
||||
TESTS.forEach((test): void => {
|
||||
describe(test, (): void => {
|
||||
const input = hexToU8a(test);
|
||||
|
||||
it('has the right encodedLength', (): void => {
|
||||
expect(
|
||||
new BitVec(registry, input).encodedLength
|
||||
).toEqual((test.length - 2) / 2);
|
||||
});
|
||||
|
||||
// FIXME These do not align at all
|
||||
it.skip('re-encodes to the same input value', (): void => {
|
||||
expect(
|
||||
new BitVec(registry, input).toU8a()
|
||||
).toEqual(input);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,66 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Bool } from '.';
|
||||
|
||||
describe('Bool', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('decode', (): void => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const testDecode = (type: string, input: Uint8Array | boolean | Boolean | Bool | number, expected: boolean): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
expect(new Bool(registry, input).toJSON()).toBe(expected);
|
||||
});
|
||||
|
||||
testDecode('Bool', new Bool(registry, true), true);
|
||||
testDecode('Boolean', Boolean(true), true);
|
||||
testDecode('boolean', true, true);
|
||||
testDecode('number', 1, true);
|
||||
testDecode('Uint8Array', Uint8Array.from([1]), true);
|
||||
});
|
||||
|
||||
describe('encode', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: string | Uint8Array | boolean, value: boolean): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
expect(new Bool(registry, value)[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toJSON', true, true);
|
||||
testEncode('toHex', '0x01', true);
|
||||
testEncode('toString', 'true', true);
|
||||
testEncode('toU8a', Uint8Array.from([1]), true);
|
||||
testEncode('toU8a', Uint8Array.from([0]), false);
|
||||
});
|
||||
|
||||
it('correctly encodes length', (): void => {
|
||||
expect(new Bool(registry, true).encodedLength).toEqual(1);
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares against a boolean', (): void => {
|
||||
expect(new Bool(registry, true).eq(true)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against a Bool', (): void => {
|
||||
expect(new Bool(registry, false).eq(new Bool(registry, false))).toBe(true);
|
||||
});
|
||||
|
||||
it('has isTrue', (): void => {
|
||||
expect(new Bool(registry, true).isTrue).toBe(true);
|
||||
});
|
||||
|
||||
it('has isFalse', (): void => {
|
||||
expect(new Bool(registry, true).isFalse).toBe(false);
|
||||
});
|
||||
|
||||
it('has sane isEmpty aligning with the rest', (): void => {
|
||||
expect(new Bool(registry).isEmpty).toBe(true);
|
||||
expect(new Bool(registry, false).isEmpty).toBe(true);
|
||||
expect(new Bool(registry, true).isEmpty).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,65 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Bytes } from '.';
|
||||
|
||||
describe('Bytes', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
const NUM = [0x3a, 0x63, 0x6f, 0x64, 0x65];
|
||||
const U8A = new Uint8Array([0x14, ...NUM]);
|
||||
const HEX = '0x3a636f6465';
|
||||
|
||||
describe('construction', (): void => {
|
||||
it('decodes when input is string', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, ':code').toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('decodes when hex is not length prefixed', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, HEX).toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('decodes from UInt8Array', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, U8A).toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('decodes from number[]', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, NUM).toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('creates via storagedata (no prefix)', (): void => {
|
||||
expect(
|
||||
new Bytes(
|
||||
registry,
|
||||
registry.createType('StorageData', HEX)
|
||||
).toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('encodes from itself', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, new Bytes(registry, HEX)).toU8a()
|
||||
).toEqual(U8A);
|
||||
});
|
||||
|
||||
it('strips length with toU8a(true)', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, HEX).toU8a(true)
|
||||
).toEqual(U8A.subarray(1));
|
||||
});
|
||||
|
||||
it('strips length with toHex', (): void => {
|
||||
expect(
|
||||
new Bytes(registry, HEX).toHex()
|
||||
).toEqual(HEX);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Null } from '.';
|
||||
|
||||
describe('Null', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('compares against null', (): void => {
|
||||
expect(new Null(registry).eq(null)).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against Null', (): void => {
|
||||
expect(new Null(registry).eq(new Null(registry))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares against other (failed)', (): void => {
|
||||
expect(new Null(registry).eq()).toBe(false);
|
||||
});
|
||||
|
||||
it('has no hash', (): void => {
|
||||
expect(
|
||||
() => new Null(registry).hash
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it('isEmpty', (): void => {
|
||||
expect(new Null(registry).isEmpty).toBe(true);
|
||||
});
|
||||
|
||||
it('has an empty hex', (): void => {
|
||||
expect(new Null(registry).toHex()).toEqual('0x');
|
||||
});
|
||||
|
||||
it('has a Null type', (): void => {
|
||||
expect(new Null(registry).toRawType()).toEqual('Null');
|
||||
});
|
||||
});
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { CodecTo } from '@polkadot/types-codec/types';
|
||||
|
||||
import { Raw } from '@polkadot/types-codec';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Bytes, Text } from '.';
|
||||
|
||||
describe('Text', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
describe('decode', (): void => {
|
||||
const testDecode = (type: string, input: null | string | Uint8Array | { toString: () => string }, expected: string, toFn: 'toString' | 'toHex' | 'toHuman' = 'toString'): void =>
|
||||
it(`can decode from ${type}`, (): void => {
|
||||
expect(new Text(registry, input)[toFn]()).toBe(expected);
|
||||
});
|
||||
|
||||
testDecode('string', 'foo', 'foo');
|
||||
testDecode('Text', new Text(registry, 'foo'), 'foo');
|
||||
testDecode('Uint8Array', Uint8Array.from([12, 102, 111, 111]), 'foo');
|
||||
testDecode('Raw', new Raw(registry, Uint8Array.from([102, 111, 111])), 'foo'); // no length
|
||||
testDecode('Raw', new Raw(registry, Uint8Array.from([102, 111, 111])), 'foo', 'toHuman'); // no length
|
||||
testDecode('Bytes', new Bytes(registry, Uint8Array.from([12, 102, 111, 111])), 'foo'); // length-aware encoding
|
||||
testDecode('Bytes', new Bytes(registry, Uint8Array.from([12, 102, 111, 111])), 'foo', 'toHuman'); // length-aware encoding
|
||||
testDecode('object with `toString()`', { toString (): string { return 'foo'; } }, 'foo');
|
||||
testDecode('hex input value', new Text(registry, '0x12345678'), '0x12345678', 'toHex');
|
||||
testDecode('null', null, '');
|
||||
});
|
||||
|
||||
describe('encode', (): void => {
|
||||
const testEncode = (to: CodecTo, expected: string | Uint8Array): void =>
|
||||
it(`can encode ${to}`, (): void => {
|
||||
expect(new Text(registry, 'foo')[to]()).toEqual(expected);
|
||||
});
|
||||
|
||||
testEncode('toHex', '0x666f6f');
|
||||
testEncode('toString', 'foo');
|
||||
testEncode('toU8a', Uint8Array.from([12, 102, 111, 111]));
|
||||
});
|
||||
|
||||
describe('utils', (): void => {
|
||||
it('compares actual string values', (): void => {
|
||||
expect(new Text(registry, '123').eq('123')).toBe(true);
|
||||
});
|
||||
|
||||
it('compares actual String values', (): void => {
|
||||
expect(new Text(registry, 'XYX').eq(String('XYX'))).toBe(true);
|
||||
});
|
||||
|
||||
it('compares actual non-string values (fails)', (): void => {
|
||||
expect(new Text(registry, '123').eq(123)).toBe(false);
|
||||
});
|
||||
|
||||
it('calulates the length & encoded length correctly for ASCII', (): void => {
|
||||
const test = new Text(registry, 'abcde');
|
||||
|
||||
expect(test.encodedLength).toEqual(6);
|
||||
expect(test).toHaveLength(5);
|
||||
});
|
||||
|
||||
it('calulates the length & encoded length correctly for non-ASCII', (): void => {
|
||||
const test = new Text(registry, '中文');
|
||||
|
||||
expect(test.encodedLength).toEqual(7);
|
||||
expect(test).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,117 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/types authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { stringToU8a, u8aConcat } from '@polkadot/util';
|
||||
|
||||
import { TypeRegistry } from '../create';
|
||||
import { Text, Type } from '.';
|
||||
|
||||
describe('Type', (): void => {
|
||||
const registry = new TypeRegistry();
|
||||
|
||||
it('fails to cleanup invalid boxes', (): void => {
|
||||
expect(
|
||||
(): Type => new Type(registry, 'Box<Proposal')
|
||||
).toThrow(/find closing matching/);
|
||||
});
|
||||
|
||||
it('cleans up tuples with a single value', (): void => {
|
||||
expect(
|
||||
new Type(registry, '(AccountId)').toString()
|
||||
).toEqual('AccountId');
|
||||
});
|
||||
|
||||
it('does not touch tuples with multiple values', (): void => {
|
||||
expect(
|
||||
new Type(registry, '(AccountId, Balance)').toString()
|
||||
).toEqual('(AccountId,Balance)');
|
||||
});
|
||||
|
||||
it('handles nested types', (): void => {
|
||||
expect(
|
||||
new Type(registry, 'Box<Vec<AccountId>>').toString()
|
||||
).toEqual('Vec<AccountId>');
|
||||
});
|
||||
|
||||
it('handles nested types (embedded)', (): void => {
|
||||
expect(
|
||||
new Type(registry, '(u32, Box<Vec<AccountId>>)').toString()
|
||||
).toEqual('(u32,Vec<AccountId>)');
|
||||
});
|
||||
|
||||
it('handles aliasses, multiples per line', (): void => {
|
||||
expect(
|
||||
new Type(registry, '(Vec<u8>, AccountId, Vec<u8>)').toString()
|
||||
).toEqual('(Bytes,AccountId,Bytes)');
|
||||
});
|
||||
|
||||
it('removes whitespaces', (): void => {
|
||||
expect(
|
||||
new Type(registry, 'T :: AccountId').toString()
|
||||
).toEqual('AccountId');
|
||||
});
|
||||
|
||||
it('changes PairOf<T> -> (T, T)', (): void => {
|
||||
expect(
|
||||
new Type(registry, 'PairOf<T::Balance>').toString()
|
||||
).toEqual('(Balance,Balance)');
|
||||
});
|
||||
|
||||
it('changes PairOf<T> (embedded) -> (T, T)', (): void => {
|
||||
expect(
|
||||
new Type(registry, '(Vec<u8>, PairOf<T::Balance>, Vec<AccountId>)').toString()
|
||||
).toEqual('(Bytes,(Balance,Balance),Vec<AccountId>)');
|
||||
});
|
||||
|
||||
it('changes () -> ()', (): void => {
|
||||
expect(
|
||||
new Type(registry, '()').toString()
|
||||
).toEqual('()');
|
||||
});
|
||||
|
||||
it('has the sanitized', (): void => {
|
||||
expect(
|
||||
new Type(
|
||||
registry,
|
||||
new Text(registry, ' Box<Proposal> ')
|
||||
).toString()
|
||||
).toEqual('Proposal'); // eslint-disable-line
|
||||
});
|
||||
|
||||
it('unwraps compact', (): void => {
|
||||
expect(
|
||||
new Type(registry, '<T::Balance as HasCompact>::Type').toString()
|
||||
).toEqual('Compact<Balance>');
|
||||
});
|
||||
|
||||
it('handles InherentOfflineReport', (): void => {
|
||||
expect(
|
||||
new Type(registry, '<T::InherentOfflineReport as InherentOfflineReport>::Inherent').toString()
|
||||
).toEqual('InherentOfflineReport');
|
||||
});
|
||||
|
||||
it('encodes correctly via toU8a()', (): void => {
|
||||
const type = 'Compact<Balance>';
|
||||
|
||||
expect(new Text(registry, type).toU8a()).toEqual(
|
||||
u8aConcat(
|
||||
new Uint8Array([type.length << 2]),
|
||||
stringToU8a(type)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('creates a decodable U8a for sanitized types', (): void => {
|
||||
const original = '<T::InherentOfflineReport as InherentOfflineReport>::Inherent';
|
||||
const expected = 'InherentOfflineReport';
|
||||
const u8a = new Type(registry, original).toU8a();
|
||||
const decoded = new Type(registry, u8a);
|
||||
|
||||
expect(decoded.encodedLength).toEqual(original.length + 1); // extra byte for length
|
||||
expect(decoded.toString()).toEqual(expected);
|
||||
});
|
||||
|
||||
it('has the correct raw', (): void => {
|
||||
expect(new Type(registry).toRawType()).toEqual('Type');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user