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', ).toBytes(), }, representations: { cashAddr: 'bitcoincash:qp3xqfv9fedx0jj7ky3wyyl5p8kggt29usvlhrrxws', legacy: '19yAQBS32jTcMFutTVCyp5e1y38JA9Qq8j', tokenAddr: 'bitcoincash:zp3xqfv9fedx0jj7ky3wyyl5p8kggt29ust4yadq3r', lockscriptBytes: Bytes.fromHex( '76a914626025854e5a67ca5eb122e213f409ec842d45e488ac', ).toBytes(), lockscriptHex: '76a914626025854e5a67ca5eb122e213f409ec842d45e488ac', lockscriptASM: 'OP_DUP OP_HASH160 OP_PUSHBYTES_20 0x626025854e5a67ca5eb122e213f409ec842d45e4 OP_EQUALVERIFY OP_CHECKSIG', hash160Bytes: Bytes.fromHex( '626025854e5a67ca5eb122e213f409ec842d45e4', ).toBytes(), 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(); }); }); });