Skip to content

Commit

Permalink
Additional test cleanups (#1870)
Browse files Browse the repository at this point in the history
* Additional test cleanups

* More compact test loops

* Correct float expected values

* Adjust
  • Loading branch information
jacogr authored Aug 23, 2023
1 parent d108bea commit a030330
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 220 deletions.
129 changes: 33 additions & 96 deletions packages/util/src/compact/toU8a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,101 +6,36 @@
import { BN } from '../bn/index.js';
import { compactToU8a } from './index.js';

// Copied from https://github.com/paritytech/parity-codec/blob/master/src/codec.rs
const TESTS: { expected: string, value: BN }[] = [
{ expected: '00', value: new BN('0') },
{ expected: 'fc', value: new BN('63') },
{ expected: '01 01', value: new BN('64') },
{ expected: 'fd ff', value: new BN('16383') },
{ expected: '02 00 01 00', value: new BN('16384') },
{ expected: 'fe ff ff ff', value: new BN('1073741823') },
{ expected: '03 00 00 00 40', value: new BN('1073741824') },
{ expected: '03 ff ff ff ff', value: new BN(`${1}${'0'.repeat(32)}`, 2).subn(1) },
{ expected: '07 00 00 00 00 01', value: new BN(`${1}${'0'.repeat(32)}`, 2) },
{ expected: '0b 00 00 00 00 00 01', value: new BN(`${1}${'0'.repeat(40)}`, 2) },
{ expected: '0f 00 00 00 00 00 00 01', value: new BN(`${1}${'0'.repeat(48)}`, 2) },
{ expected: '0f ff ff ff ff ff ff ff', value: new BN(`${1}${'0'.repeat(56)}`, 2).subn(1) },
{ expected: '13 00 00 00 00 00 00 00 01', value: new BN(`${1}${'0'.repeat(56)}`, 2) },
{ expected: '13 ff ff ff ff ff ff ff ff', value: new BN(`${1}${'0'.repeat(64)}`, 2).subn(1) }
const TESTS: [output: string | Uint8Array, input: BN | number][] = [
// Rust tests
// Copied from https://github.com/paritytech/parity-codec/blob/master/src/codec.rs
['00', new BN('0')],
['fc', new BN('63')],
['01 01', new BN('64')],
['fd ff', new BN('16383')],
['02 00 01 00', new BN('16384')],
['fe ff ff ff', new BN('1073741823')],
['03 00 00 00 40', new BN('1073741824')],
['03 ff ff ff ff', new BN(`${1}${'0'.repeat(32)}`, 2).subn(1)],
['07 00 00 00 00 01', new BN(`${1}${'0'.repeat(32)}`, 2)],
['0b 00 00 00 00 00 01', new BN(`${1}${'0'.repeat(40)}`, 2)],
['0f 00 00 00 00 00 00 01', new BN(`${1}${'0'.repeat(48)}`, 2)],
['0f ff ff ff ff ff ff ff', new BN(`${1}${'0'.repeat(56)}`, 2).subn(1)],
['13 00 00 00 00 00 00 00 01', new BN(`${1}${'0'.repeat(56)}`, 2)],
['13 ff ff ff ff ff ff ff ff', new BN(`${1}${'0'.repeat(64)}`, 2).subn(1)],
// own tests
[new Uint8Array([18 << 2]), 18],
[new Uint8Array([0b11111100]), 63],
[new Uint8Array([0xbd, 0x01]), 111],
[new Uint8Array([0b11111101, 0b00000111]), 511],
[new Uint8Array([253, 127]), 0x1fff],
[new Uint8Array([254, 255, 3, 0]), 0xffff],
[new Uint8Array([3 + ((4 - 4) << 2), 249, 255, 255, 255]), 0xfffffff9],
[new Uint8Array([3 + ((6 - 4) << 2), 0x00, 0x40, 0x7a, 0x10, 0xf3, 0x5a]), new BN('00005af3107a4000', 16)],
[new Uint8Array([23, 52, 0x40, 0x7a, 0x10, 0xf3, 0x5a, 0, 0, 18]), new BN('1200005af3107a4034', 16)]
];

describe('encode', (): void => {
it('encodes short u8', (): void => {
expect(
compactToU8a(18)
).toEqual(
new Uint8Array([18 << 2])
);
});

it('encodes max u8 values', (): void => {
expect(
compactToU8a(new BN(63))
).toEqual(
new Uint8Array([0b11111100])
);
});

it('encodes basic u16 value', (): void => {
expect(
compactToU8a(511)
).toEqual(
new Uint8Array([0b11111101, 0b00000111])
);
});

it('encodes basic u16 (not at edge)', (): void => {
expect(
compactToU8a(111)
).toEqual(
new Uint8Array([0xbd, 0x01])
);
});

it('encodes basic u32 values (< 2^30)', (): void => {
expect(
compactToU8a(0x1fff)
).toEqual(
new Uint8Array([253, 127])
);
});

it('encodes basic u32 values (short)', (): void => {
expect(
compactToU8a(0xffff)
).toEqual(
new Uint8Array([254, 255, 3, 0])
);
});

it('encodes basic u32 values (full)', (): void => {
expect(
compactToU8a(0xfffffff9)
).toEqual(
new Uint8Array([3 + ((4 - 4) << 2), 249, 255, 255, 255])
);
});

it('encodes a large value (6 bytes)', (): void => {
expect(
compactToU8a(
new BN('00005af3107a4000', 16)
)
).toEqual(
new Uint8Array([3 + ((6 - 4) << 2), 0x00, 0x40, 0x7a, 0x10, 0xf3, 0x5a])
);
});

it('encodes a large value (9 bytes)', (): void => {
expect(
compactToU8a(
new BN('1200005af3107a4034', 16)
)
).toEqual(
new Uint8Array([23, 52, 0x40, 0x7a, 0x10, 0xf3, 0x5a, 0, 0, 18])
);
});

it('does not modify the original', (): void => {
const original = new BN(123456);

Expand All @@ -109,12 +44,14 @@ describe('encode', (): void => {
});

describe('conversion tests', (): void => {
TESTS.forEach(({ expected, value }, i): void => {
it(`#${i}: encodes ${value.toString()}`, (): void => {
TESTS.forEach(([output, input], i): void => {
it(`#${i}: encodes ${input.toString()}`, (): void => {
expect(
compactToU8a(value)
compactToU8a(input)
).toEqual(
Uint8Array.from(expected.split(' ').map((s) => parseInt(s, 16)))
output instanceof Uint8Array
? output
: Uint8Array.from(output.split(' ').map((s) => parseInt(s, 16)))
);
});
});
Expand Down
110 changes: 29 additions & 81 deletions packages/util/src/float/toU8a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,32 @@
import { u8aToHex } from '../u8a/index.js';
import { floatToU8a } from './index.js';

class ExtNumber extends Number {
foo = 'bar';
}

class ExtString extends String {
foo = 'bar';
}

// NOTE Hex value outputs created via online conversion tool:
// https://www.h-schmidt.net/FloatConverter/IEEE754.html
// eslint-disable-next-line @typescript-eslint/ban-types
const TESTS: [isLe: boolean | undefined, bitLength: 32 | 64 | undefined, input: String | string | number | Number, output: string][] = [
[undefined, undefined, +0.0, '0x00000000'],
[undefined, undefined, -0.0, '0x00000080'],
[undefined, undefined, 123.456, '0x79e9f642'],
[undefined, undefined, '123.456', '0x79e9f642'],
[undefined, undefined, new ExtNumber(123.456), '0x79e9f642'],
[undefined, undefined, new ExtString(123.456), '0x79e9f642'],
[true, 32, new ExtString(123.456), '0x79e9f642'],
[true, undefined, Number.NaN, '0x0000c07f'],
[false, undefined, -0.0, '0x80000000'],
[undefined, 64, +0.0, '0x0000000000000000'],
[true, 64, -0.0, '0x0000000000000080'],
[false, 64, -0.0, '0x8000000000000000'],
[undefined, 64, Number.NaN, '0x000000000000f87f']
];

describe('floatToU8a', (): void => {
it('throws on invalid bitLength', (): void => {
Expand All @@ -16,89 +40,13 @@ describe('floatToU8a', (): void => {
).toThrow();
});

describe('32-bit', (): void => {
it('correctly encodes +0.0', (): void => {
expect(
u8aToHex(floatToU8a(+0.0))
).toEqual('0x00000000');
});

it('correctly encodes -0.0', (): void => {
expect(
u8aToHex(floatToU8a(-0.0))
).toEqual('0x00000080');
});

it('correctly encodes -0.0 (BE)', (): void => {
expect(
u8aToHex(floatToU8a(-0.0, { isLe: false }))
).toEqual('0x80000000');
});

it('encodes NaN', (): void => {
expect(
u8aToHex(floatToU8a(Number.NaN, { isLe: true }))
).toEqual('0x0000c07f');
});

describe('equivalency', (): void => {
it('encodes number 123.456', (): void => {
expect(
u8aToHex(floatToU8a(123.456))
).toEqual('0x79e9f642');
});

it('encodes string 123.456', (): void => {
expect(
u8aToHex(floatToU8a('123.456'))
).toEqual('0x79e9f642');
});

it('encodes Number 123.456', (): void => {
class Test extends Number {
foo = 'bar';
}

expect(
u8aToHex(floatToU8a(new Test(123.456)))
).toEqual('0x79e9f642');
});

it('encodes String 123.456', (): void => {
class Test extends String {
foo = 'bar';
}

describe('conversion tests', (): void => {
TESTS.forEach(([isLe, bitLength, input, output], i): void => {
it(`#${i}: correctly encodes ${typeof input === 'number' ? input : input.toString()} (typeof=${typeof input})`, (): void => {
expect(
u8aToHex(floatToU8a(new Test('123.456')))
).toEqual('0x79e9f642');
u8aToHex(floatToU8a(input, { bitLength, isLe }))
).toEqual(output);
});
});
});

describe('64-bit', (): void => {
it('correctly encodes +0.0', (): void => {
expect(
u8aToHex(floatToU8a(+0.0, { bitLength: 64 }))
).toEqual('0x0000000000000000');
});

it('correctly encodes -0.0', (): void => {
expect(
u8aToHex(floatToU8a(-0.0, { bitLength: 64, isLe: true }))
).toEqual('0x0000000000000080');
});

it('correctly encodes -0.0 (BE)', (): void => {
expect(
u8aToHex(floatToU8a(-0.0, { bitLength: 64, isLe: false }))
).toEqual('0x8000000000000000');
});

it('encodes NaN', (): void => {
expect(
u8aToHex(floatToU8a(Number.NaN, { bitLength: 64 }))
).toEqual('0x000000000000f87f');
});
});
});
65 changes: 22 additions & 43 deletions packages/util/src/u8a/toU8a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,21 @@

/// <reference types="@polkadot/dev-test/globals.d.ts" />

import type { U8aLike } from '../types.js';

import { perf } from '../test/index.js';
import { u8aToU8a } from './index.js';

const TESTS: [input: U8aLike | null | undefined, output: Uint8Array][] = [
['0x80000a', new Uint8Array([128, 0, 10])],
['abcde fghij', new Uint8Array([97, 98, 99, 100, 101, 32, 102, 103, 104, 105, 106])],
[[128, 0, 10, 11, 12], new Uint8Array([128, 0, 10, 11, 12])],
[Buffer.from([1, 2, 3, 128, 0, 10, 11, 12]), new Uint8Array([1, 2, 3, 128, 0, 10, 11, 12])],
[Buffer.from('80000a', 'hex'), new Uint8Array([128, 0, 10])],
// this is where completely invalid data is being passed
[123 as unknown as Uint8Array, new Uint8Array([49, 50, 51])]
];

describe('u8aToU8a', (): void => {
it('returns an empty Uint8Array when null/undefined/"" provided', (): void => {
expect(
Expand All @@ -19,44 +31,6 @@ describe('u8aToU8a', (): void => {
).toHaveLength(0);
});

it('returns a Uint8Array (hex input)', (): void => {
expect(
u8aToU8a('0x80000a')
).toEqual(
new Uint8Array([128, 0, 10])
);
});

it('returns Uint8Array (string input)', (): void => {
expect(
u8aToU8a('abcde fghij')
).toEqual(new Uint8Array([97, 98, 99, 100, 101, 32, 102, 103, 104, 105, 106]));
});

it('creates from Array', (): void => {
expect(
u8aToU8a([128, 0, 10, 11, 12])
).toEqual(
new Uint8Array([128, 0, 10, 11, 12])
);
});

it('creates from a Buffer', (): void => {
expect(
u8aToU8a(Buffer.from([1, 2, 3, 128, 0, 10, 11, 12])).buffer
).toEqual(
new Uint8Array([1, 2, 3, 128, 0, 10, 11, 12]).buffer
);
});

it('creates from a Buffer (hex)', (): void => {
expect(
u8aToU8a(Buffer.from('80000a', 'hex')).buffer
).toEqual(
new Uint8Array([128, 0, 10]).buffer
);
});

it('returns a Uint8Array as-is (u8a input)', (): void => {
const input = new Uint8Array([128, 0, 10]);

Expand All @@ -65,11 +39,16 @@ describe('u8aToU8a', (): void => {
).toEqual(true);
});

it('creates unknowns via string conversion', (): void => {
expect(
// this is where completely invalid data is being passed
u8aToU8a(123 as unknown as Uint8Array)
).toEqual(new Uint8Array([49, 50, 51]));
describe('conversion tests', (): void => {
TESTS.forEach(([input, output], i): void => {
it(`#${i}: converts ${input as string} (typeof=${typeof input})`, (): void => {
expect(
u8aToU8a(input)
).toEqual(
output
);
});
});
});

perf('u8aToU8a (hex)', 250_000, [['0x1234']], u8aToU8a);
Expand Down

0 comments on commit a030330

Please sign in to comment.