UNPKG

@projectlibertylabs/p2p-peer-test

Version:

CLI tool to test libp2p connections and discover peer protocols

240 lines (208 loc) 7.4 kB
import { describe, it, expect } from 'vitest'; import { parseMultiaddrs, safeParseInt, measureDuration, pipe, compose, isNullOrUndefined, isEmpty, createPromiseWithTimeout } from './utils.js'; describe('parseMultiaddrs', () => { it('should parse single multiaddr', () => { const input = '/ip4/127.0.0.1/tcp/4001'; const result = parseMultiaddrs(input); expect(result).toEqual(['/ip4/127.0.0.1/tcp/4001']); }); it('should parse multiple multiaddrs separated by newlines', () => { const input = `/ip4/127.0.0.1/tcp/4001 /ip4/127.0.0.1/tcp/4002 /ip4/127.0.0.1/tcp/4003`; const result = parseMultiaddrs(input); expect(result).toEqual([ '/ip4/127.0.0.1/tcp/4001', '/ip4/127.0.0.1/tcp/4002', '/ip4/127.0.0.1/tcp/4003' ]); }); it('should parse multiaddrs with mixed whitespace', () => { const input = '/ip4/127.0.0.1/tcp/4001 /ip4/127.0.0.1/tcp/4002\n\n/ip4/127.0.0.1/tcp/4003'; const result = parseMultiaddrs(input); expect(result).toEqual([ '/ip4/127.0.0.1/tcp/4001', '/ip4/127.0.0.1/tcp/4002', '/ip4/127.0.0.1/tcp/4003' ]); }); it('should filter out non-multiaddr lines', () => { const input = `/ip4/127.0.0.1/tcp/4001 # This is a comment /ip4/127.0.0.1/tcp/4002 invalid line /ip4/127.0.0.1/tcp/4003`; const result = parseMultiaddrs(input); expect(result).toEqual([ '/ip4/127.0.0.1/tcp/4001', '/ip4/127.0.0.1/tcp/4002', '/ip4/127.0.0.1/tcp/4003' ]); }); it('should remove duplicates', () => { const input = `/ip4/127.0.0.1/tcp/4001 /ip4/127.0.0.1/tcp/4002 /ip4/127.0.0.1/tcp/4001 /ip4/127.0.0.1/tcp/4003`; const result = parseMultiaddrs(input); expect(result).toEqual([ '/ip4/127.0.0.1/tcp/4001', '/ip4/127.0.0.1/tcp/4002', '/ip4/127.0.0.1/tcp/4003' ]); }); it('should handle empty input', () => { expect(parseMultiaddrs('')).toEqual([]); expect(parseMultiaddrs(' ')).toEqual([]); expect(parseMultiaddrs(null)).toEqual([]); expect(parseMultiaddrs(undefined)).toEqual([]); }); it('should trim whitespace from addresses', () => { const input = ' /ip4/127.0.0.1/tcp/4001 \n /ip4/127.0.0.1/tcp/4002 '; const result = parseMultiaddrs(input); expect(result).toEqual(['/ip4/127.0.0.1/tcp/4001', '/ip4/127.0.0.1/tcp/4002']); }); it('should handle real-world paste example', () => { const input = `/dns4/3.collator.frequency.xyz/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB /ip4/10.40.10.23/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB /ip4/3.129.100.199/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB`; const result = parseMultiaddrs(input); expect(result).toHaveLength(3); expect(result[0]).toBe( '/dns4/3.collator.frequency.xyz/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB' ); expect(result[1]).toBe( '/ip4/10.40.10.23/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB' ); expect(result[2]).toBe( '/ip4/3.129.100.199/tcp/30333/p2p/12D3KooWLsZTXsv1eY6U9YhowipQ73R5D1zQTaWECUCkxLawWpoB' ); }); }); describe('safeParseInt', () => { it('should parse valid integer string', () => { expect(safeParseInt('123', 0)).toBe(123); expect(safeParseInt('0', 10)).toBe(0); expect(safeParseInt('-5', 0)).toBe(-5); }); it('should return default value for invalid input', () => { expect(safeParseInt('abc', 42)).toBe(null); expect(safeParseInt('', 10)).toBe(10); expect(safeParseInt(null, 5)).toBe(5); }); it('should use validator function when provided', () => { const positiveValidator = (n) => n > 0; expect(safeParseInt('10', 0, positiveValidator)).toBe(10); expect(safeParseInt('-5', 0, positiveValidator)).toBe(null); expect(safeParseInt('0', 1, positiveValidator)).toBe(null); }); it('should handle numeric input', () => { expect(safeParseInt(123, 0)).toBe(123); expect(safeParseInt(0, 10)).toBe(10); // 0 is falsy, so uses default }); }); describe('measureDuration', () => { it('should return positive duration', () => { const start = performance.now() - 100; // 100ms ago const duration = measureDuration(start); expect(duration).toBeGreaterThan(90); expect(duration).toBeLessThan(200); // Allow some variance expect(Number.isInteger(duration)).toBe(true); }); it('should return 0 or positive for current time', () => { const start = performance.now(); const duration = measureDuration(start); expect(duration).toBeGreaterThanOrEqual(0); expect(Number.isInteger(duration)).toBe(true); }); }); describe('pipe', () => { it('should apply functions left to right', () => { const add5 = (x) => x + 5; const multiply2 = (x) => x * 2; const subtract1 = (x) => x - 1; const piped = pipe(add5, multiply2, subtract1); expect(piped(10)).toBe(29); // ((10 + 5) * 2) - 1 = 29 }); it('should work with single function', () => { const double = (x) => x * 2; const piped = pipe(double); expect(piped(5)).toBe(10); }); it('should work with no functions', () => { const piped = pipe(); expect(piped(42)).toBe(42); }); }); describe('compose', () => { it('should apply functions right to left', () => { const add5 = (x) => x + 5; const multiply2 = (x) => x * 2; const subtract1 = (x) => x - 1; const composed = compose(subtract1, multiply2, add5); expect(composed(10)).toBe(29); // ((10 + 5) * 2) - 1 = 29 }); it('should work with single function', () => { const double = (x) => x * 2; const composed = compose(double); expect(composed(5)).toBe(10); }); }); describe('isNullOrUndefined', () => { it('should return true for null and undefined', () => { expect(isNullOrUndefined(null)).toBe(true); expect(isNullOrUndefined(undefined)).toBe(true); }); it('should return false for other values', () => { expect(isNullOrUndefined(0)).toBe(false); expect(isNullOrUndefined('')).toBe(false); expect(isNullOrUndefined(false)).toBe(false); expect(isNullOrUndefined([])).toBe(false); expect(isNullOrUndefined({})).toBe(false); }); }); describe('isEmpty', () => { it('should return true for empty values', () => { expect(isEmpty(null)).toBe(true); expect(isEmpty(undefined)).toBe(true); expect(isEmpty('')).toBe(true); expect(isEmpty(' ')).toBe(true); expect(isEmpty([])).toBe(true); }); it('should return false for non-empty values', () => { expect(isEmpty('hello')).toBe(false); expect(isEmpty('0')).toBe(false); expect(isEmpty([1])).toBe(false); expect(isEmpty(0)).toBe(false); expect(isEmpty(false)).toBe(false); expect(isEmpty({})).toBe(false); }); }); describe('createPromiseWithTimeout', () => { it('should resolve when promise resolves before timeout', async () => { const fastPromise = Promise.resolve('success'); const result = await createPromiseWithTimeout(fastPromise, 1000, 'timeout'); expect(result).toBe('success'); }); it('should reject with timeout error when promise takes too long', async () => { const slowPromise = new Promise((resolve) => setTimeout(() => resolve('late'), 100)); await expect( createPromiseWithTimeout(slowPromise, 10, 'Custom timeout message') ).rejects.toThrow('Custom timeout message'); }); it('should reject with original error when promise rejects', async () => { const failingPromise = Promise.reject(new Error('Original error')); await expect(createPromiseWithTimeout(failingPromise, 1000, 'timeout')).rejects.toThrow( 'Original error' ); }); });