Skip to content

Commit

Permalink
refactor: create HexUInt32 class (#1776)
Browse files Browse the repository at this point in the history
* refactor: create HexUInt32 class

* refactor: add extra check length in test

* refactor: add method to validate length
  • Loading branch information
saraantole authored Jan 31, 2025
1 parent ff326dc commit f8699f2
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
74 changes: 74 additions & 0 deletions packages/core/src/vcdm/HexUInt32.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { InvalidDataType } from '@vechain/sdk-errors';
import { type HexInt } from './HexInt';
import { HexUInt } from './HexUInt';

/**
* Represents a 32-byte hexadecimal unsigned integer.
*
* @extends HexUInt
*/
class HexUInt32 extends HexUInt {
/**
* Expected byte length.
* @type {number}
*/
private static readonly BYTE_LENGTH = 32;

/**
* Regular expression for matching 32 bytes hexadecimal strings.
* An empty input is represented as a empty digits.
*
* @type {RegExp}
*/
private static readonly REGEX_HEXUINT32: RegExp = /^(0x)?[0-9a-f]{64}$/i;

/**
* Checks if the given string expression is a valid 32 bytes unsigned hexadecimal value.
*
* @param {string} exp - The string representation of a hexadecimal value.
*
* @return {boolean} - True if the expression is a valid 32 bytes unsigned hexadecimal value, case-insensitive,
* optionally prefixed with `0x`; false otherwise.
*/
public static isValid(exp: string): boolean {
return HexUInt32.REGEX_HEXUINT32.test(exp);
}

/**
* Ensures the hexadecimal string representation is 32 bytes long.
* @param {string} hexString - The hexadecimal string to validate.
* @returns {string} The 32 bytes long hexadecimal string.
*/
private static convertTo32Bytes(hexString: string): string {
const nonPrefixedHex = hexString.replace(/^0x/, '');

return nonPrefixedHex.padStart(this.BYTE_LENGTH * 2, '0');
}

/**
* Creates a HexUInt32 instance with enforced 32 bytes length.
* @param {bigint | number | string | Uint8Array | HexInt} exp - The expression to convert.
* @returns {HexUInt32} The HexUInt32 object representing the given expression.
* @throws {InvalidDataType} If the value is not a valid 32-byte hex string.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexInt
): HexUInt32 {
try {
const hexUInt = HexUInt.of(exp);

const hexDigits = this.convertTo32Bytes(hexUInt.toString());

return new HexUInt32(hexUInt.sign, hexDigits);
} catch (e) {
throw new InvalidDataType(
'HexUInt32.of',
'not a 32 bytes long hexadecimal positive integer expression',
{ exp: `${exp}`, e },
e
);
}
}
}

export { HexUInt32 };
47 changes: 47 additions & 0 deletions packages/core/tests/vcdm/HexUInt32.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, test } from '@jest/globals';
import { InvalidDataType } from '@vechain/sdk-errors';
import { HexUInt32 } from '../../src/vcdm/HexUInt32';

/**
* Test HexUInt32 class.
* @group unit/vcdm
*/
describe('HexUInt32 class tests', () => {
describe('Construction tests', () => {
test('Return an HexUInt32 instance of the provided expression', () => {
const expression = '0xcaffee';
const expectedHexUInt32 =
'0x0000000000000000000000000000000000000000000000000000000000caffee';

const hexUInt32 = HexUInt32.of(expression);

expect(hexUInt32).toBeInstanceOf(HexUInt32);
expect(hexUInt32.toString()).toEqual(expectedHexUInt32);
});

test('Checks if the provided expression is a valid 32 bytes unsigned hexadecimal value', () => {
const expression =
'0x0000000000000000000000000000000000000000000000000000000000caffee';

expect(HexUInt32.isValid(expression)).toBeTruthy();
});

test('Throw an error if the provided argument is not an unsigned expression', () => {
const exp = '-0xnotUnsigned';
expect(() => HexUInt32.of(exp)).toThrow(InvalidDataType);
});
});

describe('Polymorphism equivalence', () => {
test('Equal for bigint, bytes, hex expression, number', () => {
const ofBigInt = HexUInt32.of(255n);
const ofBytes = HexUInt32.of(Uint8Array.of(255));
const ofHex = HexUInt32.of('0xff');
const ofNumber = HexUInt32.of(255);
expect(ofBigInt.toString()).toHaveLength(66);
expect(ofBigInt.isEqual(ofBytes)).toBeTruthy();
expect(ofBytes.isEqual(ofHex)).toBeTruthy();
expect(ofHex.isEqual(ofNumber)).toBeTruthy();
});
});
});

1 comment on commit f8699f2

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage

Summary

Lines Statements Branches Functions
Coverage: 86%
86.43% (1721/1991) 85.42% (586/686) 72% (342/475)
Title Tests Skipped Failures Errors Time
core 840 0 💤 0 ❌ 0 🔥 42.716s ⏱️

Please sign in to comment.