/** * Tests for hexToArrayBuffer utility function. * * Obsidian API: `function hexToArrayBuffer(hex: string): ArrayBuffer` */ import { describe, it, expect } from 'vitest' import { hexToArrayBuffer, arrayBufferToHex } from '../obsidian-stubs' describe('hexToArrayBuffer', () => { it('returns empty ArrayBuffer for empty string', () => { const buffer = hexToArrayBuffer('') expect(buffer.byteLength).toBe(0) }) it('converts "00" to single byte 0x00', () => { const buffer = hexToArrayBuffer('00') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(1) expect(bytes[0]).toBe(0x00) }) it('converts "ff" to single byte 0xff', () => { const buffer = hexToArrayBuffer('ff') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(1) expect(bytes[0]).toBe(0xff) }) it('converts "deadbeef" to multi-byte array', () => { const buffer = hexToArrayBuffer('deadbeef') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(4) expect(bytes[0]).toBe(0xde) expect(bytes[1]).toBe(0xad) expect(bytes[2]).toBe(0xbe) expect(bytes[3]).toBe(0xef) }) it('handles uppercase hex characters', () => { const buffer = hexToArrayBuffer('ABCDEF') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(3) expect(bytes[0]).toBe(0xab) expect(bytes[1]).toBe(0xcd) expect(bytes[2]).toBe(0xef) }) it('handles mixed case hex characters', () => { const buffer = hexToArrayBuffer('AbCdEf') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(3) expect(bytes[0]).toBe(0xab) expect(bytes[1]).toBe(0xcd) expect(bytes[2]).toBe(0xef) }) it('converts "0a0b0c" correctly with leading zeros', () => { const buffer = hexToArrayBuffer('0a0b0c') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(3) expect(bytes[0]).toBe(0x0a) expect(bytes[1]).toBe(0x0b) expect(bytes[2]).toBe(0x0c) }) it('converts "00010203" correctly', () => { const buffer = hexToArrayBuffer('00010203') const bytes = new Uint8Array(buffer) expect(bytes.length).toBe(4) expect(bytes[0]).toBe(0x00) expect(bytes[1]).toBe(0x01) expect(bytes[2]).toBe(0x02) expect(bytes[3]).toBe(0x03) }) it('is the inverse of arrayBufferToHex', () => { const original = new Uint8Array([0xde, 0xad, 0xbe, 0xef]).buffer const hex = arrayBufferToHex(original) const roundTrip = hexToArrayBuffer(hex) const originalBytes = new Uint8Array(original) const roundTripBytes = new Uint8Array(roundTrip) expect(roundTripBytes).toEqual(originalBytes) }) it('round-trips empty buffer correctly', () => { const original = new ArrayBuffer(0) const hex = arrayBufferToHex(original) const roundTrip = hexToArrayBuffer(hex) expect(roundTrip.byteLength).toBe(0) }) // Error handling tests it('throws on odd-length hex string', () => { expect(() => hexToArrayBuffer('abc')).toThrow('hex string must have even length') expect(() => hexToArrayBuffer('a')).toThrow('hex string must have even length') expect(() => hexToArrayBuffer('12345')).toThrow('hex string must have even length') }) it('throws on invalid hex characters', () => { expect(() => hexToArrayBuffer('zz')).toThrow('invalid hex characters') expect(() => hexToArrayBuffer('gh')).toThrow('invalid hex characters') expect(() => hexToArrayBuffer('0x12')).toThrow('invalid hex characters') // "x" is invalid expect(() => hexToArrayBuffer('1234 ')).toThrow('invalid hex characters') // space is invalid (even length) }) // Round-trip in the other direction (hex -> buffer -> hex) it('round-trips hex to lowercase (arrayBufferToHex outputs lowercase)', () => { // hexToArrayBuffer accepts uppercase, arrayBufferToHex outputs lowercase const hex = 'DEADBEEF' const buffer = hexToArrayBuffer(hex) const roundTrip = arrayBufferToHex(buffer) expect(roundTrip).toBe('deadbeef') // normalized to lowercase }) })