package utils import ( "bytes" "reflect" "testing" ) func TestByteBuffer_Append(t *testing.T) { b := &ByteBuffer{} b.Append([]byte("hello")) b.Append([]byte(" ")) b.Append([]byte("world")) if string(b.Buf) != "hello world" { t.Errorf("Append() result = %q, want %q", string(b.Buf), "hello world") } } func TestByteBuffer_Len(t *testing.T) { b := &ByteBuffer{} if b.Len() != 0 { t.Errorf("Len() = %d, want 0", b.Len()) } b.Append([]byte("abc")) if b.Len() != 3 { t.Errorf("Len() = %d, want 3", b.Len()) } } func TestByteBuffer_Index(t *testing.T) { b := &ByteBuffer{Buf: []byte("hello world")} if i := b.Index([]byte("world")); i != 6 { t.Errorf("Index('world') = %d, want 6", i) } if i := b.Index([]byte("xyz")); i != -1 { t.Errorf("Index('xyz') = %d, want -1", i) } if i := b.Index([]byte{}); i != 0 { t.Errorf("Index('') = %d, want 0", i) } } func TestByteBuffer_Get(t *testing.T) { b := &ByteBuffer{Buf: []byte("abcdef")} data, ok := b.Get(3, true) if !ok { t.Fatal("Get(3, true) returned false") } if !bytes.Equal(data, []byte("abc")) { t.Errorf("Get(3, true) data = %q, want %q", data, "abc") } if !bytes.Equal(b.Buf, []byte("def")) { t.Errorf("after consume, Buf = %q, want %q", b.Buf, "def") } data, ok = b.Get(4, false) if ok { t.Fatal("Get(4, false) should return false (only 3 bytes left)") } data, ok = b.Get(2, false) if !ok { t.Fatal("Get(2, false) returned false") } if !bytes.Equal(data, []byte("de")) { t.Errorf("Get(2, false) data = %q, want %q", data, "de") } if !bytes.Equal(b.Buf, []byte("def")) { t.Errorf("after non-consume, Buf = %q, want %q (unchanged)", b.Buf, "def") } data, ok = b.Get(3, true) if !ok { t.Fatal("Get(3, true) returned false") } if !bytes.Equal(data, []byte("def")) { t.Errorf("Get(3, true) data = %q, want %q", data, "def") } if b.Len() != 0 { t.Errorf("after consume all, Len() = %d, want 0", b.Len()) } } func TestByteBuffer_GetString(t *testing.T) { b := &ByteBuffer{Buf: []byte("hello world")} s, ok := b.GetString(5, true) if !ok { t.Fatal("GetString(5, true) returned false") } if s != "hello" { t.Errorf("GetString() = %q, want %q", s, "hello") } if b.Len() != 6 { t.Errorf("after consume, Len() = %d, want 6", b.Len()) } s, ok = b.GetString(7, false) if ok { t.Fatal("GetString(7, false) should return false") } s, ok = b.GetString(6, false) if !ok { t.Fatal("GetString(6, false) returned false") } if s != " world" { t.Errorf("GetString() = %q, want %q", s, " world") } } func TestByteBuffer_GetByte(t *testing.T) { b := &ByteBuffer{Buf: []byte("abc")} bt, ok := b.GetByte(true) if !ok { t.Fatal("GetByte(true) returned false") } if bt != 'a' { t.Errorf("GetByte() = %c, want 'a'", bt) } if b.Len() != 2 { t.Errorf("after consume, Len() = %d, want 2", b.Len()) } bt, ok = b.GetByte(false) if !ok { t.Fatal("GetByte(false) returned false") } if bt != 'b' { t.Errorf("GetByte() = %c, want 'b'", bt) } if b.Len() != 2 { t.Errorf("after non-consume, Len() = %d, want 2 (unchanged)", b.Len()) } b.GetByte(true) b.GetByte(true) bt, ok = b.GetByte(true) if ok { t.Fatal("GetByte(true) on empty buffer should return false") } } func TestByteBuffer_GetUint16(t *testing.T) { b := &ByteBuffer{Buf: []byte{0x01, 0x02, 0x03, 0x04}} v, ok := b.GetUint16(false, true) if !ok { t.Fatal("GetUint16(bigEndian) returned false") } if v != 0x0102 { t.Errorf("GetUint16(bigEndian) = 0x%04x, want 0x0102", v) } if b.Len() != 2 { t.Errorf("after consume, Len() = %d, want 2", b.Len()) } v, ok = b.GetUint16(true, true) if !ok { t.Fatal("GetUint16(littleEndian) returned false") } if v != 0x0403 { t.Errorf("GetUint16(littleEndian) = 0x%04x, want 0x0403", v) } v, ok = b.GetUint16(false, false) if ok { t.Fatal("GetUint16 on empty buffer should return false") } } func TestByteBuffer_GetUint32(t *testing.T) { b := &ByteBuffer{Buf: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}} v, ok := b.GetUint32(false, true) if !ok { t.Fatal("GetUint32(bigEndian) returned false") } if v != 0x01020304 { t.Errorf("GetUint32(bigEndian) = 0x%08x, want 0x01020304", v) } if b.Len() != 4 { t.Errorf("after consume, Len() = %d, want 4", b.Len()) } v, ok = b.GetUint32(true, true) if !ok { t.Fatal("GetUint32(littleEndian) returned false") } if v != 0x08070605 { t.Errorf("GetUint32(littleEndian) = 0x%08x, want 0x08070605", v) } v, ok = b.GetUint32(false, false) if ok { t.Fatal("GetUint32 on empty buffer should return false") } } func TestByteBuffer_GetUntil(t *testing.T) { b := &ByteBuffer{Buf: []byte("hello\r\nworld\r\n")} data, ok := b.GetUntil([]byte("\r\n"), true, true) if !ok { t.Fatal("GetUntil(sep, include) returned false") } if !bytes.Equal(data, []byte("hello\r\n")) { t.Errorf("GetUntil(include) = %q, want %q", data, "hello\\r\\n") } data, ok = b.GetUntil([]byte("\r\n"), false, false) if !ok { t.Fatal("GetUntil(sep, exclude, non-consume) returned false") } if !bytes.Equal(data, []byte("world")) { t.Errorf("GetUntil(exclude) = %q, want %q", data, "world") } if b.Len() != 7 { t.Errorf("after non-consume, Len() = %d, want 7", b.Len()) } data, ok = b.GetUntil([]byte("\r\n"), true, true) if !ok { t.Fatal("GetUntil second (consume) returned false") } if !bytes.Equal(data, []byte("world\r\n")) { t.Errorf("GetUntil second = %q, want %q", data, "world\\r\\n") } _, ok = b.GetUntil([]byte("xyz"), false, false) if ok { t.Fatal("GetUntil(not found) should return false") } } func TestByteBuffer_GetSubBuffer(t *testing.T) { b := &ByteBuffer{Buf: []byte("hello world")} sub, ok := b.GetSubBuffer(5, true) if !ok { t.Fatal("GetSubBuffer() returned false") } if !bytes.Equal(sub.Buf, []byte("hello")) { t.Errorf("GetSubBuffer() = %q, want %q", sub.Buf, "hello") } if b.Len() != 6 { t.Errorf("after consume, Len() = %d, want 6", b.Len()) } _, ok = b.GetSubBuffer(7, false) if ok { t.Fatal("GetSubBuffer(7) should return false (only 6 bytes left)") } } func TestByteBuffer_Skip(t *testing.T) { b := &ByteBuffer{Buf: []byte("abcdef")} ok := b.Skip(2) if !ok { t.Fatal("Skip(2) returned false") } if !bytes.Equal(b.Buf, []byte("cdef")) { t.Errorf("after Skip(2), Buf = %q, want %q", b.Buf, "cdef") } ok = b.Skip(10) if ok { t.Fatal("Skip(10) should return false") } if !bytes.Equal(b.Buf, []byte("cdef")) { t.Errorf("after failed Skip, Buf = %q, want %q (unchanged)", b.Buf, "cdef") } ok = b.Skip(4) if !ok { t.Fatal("Skip(4) returned false") } if b.Len() != 0 { t.Errorf("after Skip all, Len() = %d, want 0", b.Len()) } } func TestByteBuffer_Reset(t *testing.T) { b := &ByteBuffer{Buf: []byte("data")} b.Reset() if b.Buf != nil { t.Errorf("after Reset, Buf = %v, want nil", b.Buf) } } func TestByteBuffer_GetZeroLength(t *testing.T) { b := &ByteBuffer{Buf: []byte("abc")} data, ok := b.Get(0, true) if !ok { t.Fatal("Get(0) returned false") } if len(data) != 0 { t.Errorf("Get(0) len = %d, want 0", len(data)) } if b.Len() != 3 { t.Errorf("after Get(0, consume), Len() = %d, want 3 (0-length consume is no-op)", b.Len()) } } func TestByteBuffer_GetConsumeDoesNotMutateReturnedSlice(t *testing.T) { b := &ByteBuffer{Buf: []byte("hello")} data, ok := b.Get(5, true) if !ok { t.Fatal("Get() returned false") } if !reflect.DeepEqual(data, []byte("hello")) { t.Errorf("Get() returned wrong data: %v", data) } if b.Len() != 0 { t.Errorf("after consume, Len() should be 0") } }