Move test files to correct packages (#4345)

* Move test files to correct packages

* Adjust
This commit is contained in:
Jaco
2021-12-17 09:45:46 +02:00
committed by GitHub
parent 4e433446e2
commit f11feb4363
118 changed files with 200 additions and 415 deletions
-191
View File
@@ -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"}>');
});
});
-184
View File
@@ -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"}>');
});
});
-81
View File
@@ -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);
});
});
});
-79
View File
@@ -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/);
});
});
-442
View File
@@ -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
);
});
});
});
-17
View File
@@ -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"}>');
});
});
-68
View File
@@ -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');
});
});
});
-41
View File
@@ -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]);
});
});
-77
View File
@@ -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);
});
});
-150
View File
@@ -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);
});
});
});
-32
View File
@@ -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>');
});
});
-93
View File
@@ -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/);
});
});
});
-66
View File
@@ -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>');
});
});
-107
View File
@@ -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
-326
View File
@@ -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]));
});
});
});
-142
View File
@@ -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)');
});
});
});
-79
View File
@@ -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');
});
});
});
-163
View File
@@ -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');
});
});
});
-183
View File
@@ -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);
});
});
});
-64
View File
@@ -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>');
});
});
+11
View File
@@ -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);
}
+17
View File
@@ -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>"}'
});
});
});
+2 -19
View File
@@ -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);
}
+1 -2
View File
@@ -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);
});
});
});
});
-66
View File
@@ -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);
});
});
});
-39
View File
@@ -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');
});
});
-70
View File
@@ -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);
});
});
});
-117
View File
@@ -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');
});
});