Files
xo-stack/packages/primitives/tests/address.spec.ts

143 lines
4.4 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { Address } from '../src/address';
import { Bytes } from '../src/bytes';
describe('Success cases', () => {
// Test cases with different address representations
type AddressCase = {
raw: {
type: 'P2PKH' | 'P2SH20' | 'P2SH32' | 'P2PK';
payload: Uint8Array;
};
representations: {
cashAddr: string;
legacy: string;
tokenAddr: string;
lockscriptBytes: Uint8Array;
lockscriptHex: string;
lockscriptASM: string;
hash160Bytes: Uint8Array;
hash160Hex: string;
};
};
const testCases: AddressCase[] = [
{
raw: {
type: 'P2PKH',
payload: Bytes.fromHex(
'626025854e5a67ca5eb122e213f409ec842d45e4',
).toUint8Array(),
},
representations: {
cashAddr: 'bitcoincash:qp3xqfv9fedx0jj7ky3wyyl5p8kggt29usvlhrrxws',
legacy: '19yAQBS32jTcMFutTVCyp5e1y38JA9Qq8j',
tokenAddr: 'bitcoincash:zp3xqfv9fedx0jj7ky3wyyl5p8kggt29ust4yadq3r',
lockscriptBytes: Bytes.fromHex(
'76a914626025854e5a67ca5eb122e213f409ec842d45e488ac',
).toUint8Array(),
lockscriptHex: '76a914626025854e5a67ca5eb122e213f409ec842d45e488ac',
lockscriptASM:
'OP_DUP OP_HASH160 OP_PUSHBYTES_20 0x626025854e5a67ca5eb122e213f409ec842d45e4 OP_EQUALVERIFY OP_CHECKSIG',
hash160Bytes: Bytes.fromHex(
'626025854e5a67ca5eb122e213f409ec842d45e4',
).toUint8Array(),
hash160Hex: '626025854e5a67ca5eb122e213f409ec842d45e4',
},
},
];
// Test from methods
const fromMethods = [
{ name: 'fromCashAddr', key: 'cashAddr' },
{ name: 'fromLegacy', key: 'legacy' },
{ name: 'fromLockscriptBytes', key: 'lockscriptBytes' },
{ name: 'fromLockscriptHex', key: 'lockscriptHex' },
{ name: 'fromHash160Bytes', key: 'hash160Bytes' },
{ name: 'fromHash160Hex', key: 'hash160Hex' },
] as const;
fromMethods.forEach(({ name, key }) => {
it.each(testCases)(`${name}()`, ({ raw, representations }) => {
const value = representations[key];
const address = Address[name](value);
expect(address.toRaw()).toStrictEqual(raw);
});
});
// Test to methods
const toMethods = [
{ name: 'toCashAddr', key: 'cashAddr' },
{ name: 'toLegacy', key: 'legacy' },
{ name: 'toTokenAddress', key: 'tokenAddr' },
{ name: 'toLockscriptBytes', key: 'lockscriptBytes' },
{ name: 'toLockscriptHex', key: 'lockscriptHex' },
{ name: 'toLockscriptAsm', key: 'lockscriptASM' },
{ name: 'toHash160Bytes', key: 'hash160Bytes' },
{ name: 'toHash160Hex', key: 'hash160Hex' },
] as const;
toMethods.forEach(({ name, key }) => {
it.each(testCases)(`${name}()`, ({ raw, representations }) => {
const address = Address.fromRaw(raw);
const expected = representations[key];
expect(address[name]()).toStrictEqual(expected);
});
});
// Test generic from method
it.each(testCases)('from(cashAddr)', ({ raw, representations }) => {
const address = Address.from(representations.cashAddr);
expect(address.toRaw()).toStrictEqual(raw);
});
it.each(testCases)('from(legacy)', ({ raw, representations }) => {
const address = Address.from(representations.legacy);
expect(address.toRaw()).toStrictEqual(raw);
});
// Test validation methods
it.each(testCases)('isValid() for CashAddr', ({ representations }) => {
expect(Address.isValid(representations.cashAddr)).toBe(true);
});
it.each(testCases)('isValid() for Legacy', ({ representations }) => {
expect(Address.isValid(representations.legacy)).toBe(true);
});
it.each(testCases)('isValidCashAddr()', ({ representations }) => {
expect(Address.isValidCashAddr(representations.cashAddr)).toBe(true);
});
it.each(testCases)('isValidLegacy()', ({ representations }) => {
expect(Address.isValidLegacy(representations.legacy)).toBe(true);
});
});
describe('Error cases', () => {
const invalidCases = [
{
method: 'fromCashAddr',
input: 'invalid:address',
},
{
method: 'fromLegacy',
input: 'invalid_legacy_address',
},
{
method: 'fromHash160Hex',
input: 'invalid_hex',
},
{
method: 'fromLockscriptHex',
input: 'invalid_hex',
},
];
invalidCases.forEach(({ method, input }) => {
it(`${method}() throws on invalid input`, () => {
expect(() => Address[method](input)).toThrow();
});
});
});