Skip to content

Commit

Permalink
Add tests for stream package
Browse files Browse the repository at this point in the history
  • Loading branch information
jonastheis committed Nov 6, 2023
1 parent 7f3042d commit 2659fb1
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 23 deletions.
41 changes: 18 additions & 23 deletions serializer/stream/byte_buffer_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package stream
package stream_test

import (
"io"
"strings"
"testing"

"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/serializer/v2/stream"
)

func TestWrite(t *testing.T) {
ws := NewByteBuffer()
func TestByteBuffer_Write(t *testing.T) {
ws := stream.NewByteBuffer()
checkWrite(t, ws, "hello", "hello")
checkWrite(t, ws, " world", "hello world")
}

func TestSeek(t *testing.T) {
ws := NewByteBuffer()
func TestByteBuffer_Seek(t *testing.T) {
ws := stream.NewByteBuffer()
checkWrite(t, ws, "hello", "hello")
checkWrite(t, ws, " world", "hello world")

Expand All @@ -34,36 +36,29 @@ func TestSeek(t *testing.T) {
checkWrite(t, ws, "!", "hello golang fans\x00\x00\x00\x00!")
}

func TestSeek_LargeGap(t *testing.T) {
ws := NewByteBuffer()
func TestByteBuffer_Seek_LargeGap(t *testing.T) {
ws := stream.NewByteBuffer()
checkSeek(t, ws, 1024, io.SeekStart, 1024)
checkWrite(t, ws, "hello", strings.Repeat("\x00", 1024)+"hello")
}

// checkWrite passes data to ws.Write and compares the resulting buffer against exp.
func checkWrite(t *testing.T, byteBuffer *ByteBuffer, data, exp string) {
func checkWrite(t *testing.T, byteBuffer *stream.ByteBuffer, data, exp string) {
nBytesWritten, err := byteBuffer.Write([]byte(data))
if err != nil {
t.Fatalf("Write(%q) failed: %v", data, err)
}
require.NoError(t, err)

if nBytesWritten != len(data) {
t.Fatalf("Write(%q) = %v; want %q", data, nBytesWritten, len(data))
}
require.EqualValues(t, len(data), nBytesWritten)

bytes, err := byteBuffer.Bytes()
require.NoError(t, err)

if string(bytes) != exp {
t.Fatalf("Write(%q) produced %q; want %q", data, string(bytes), exp)
}
require.EqualValues(t, exp, string(bytes))
}

// checkSeek calls ws.Seek with the supplied parameters and compares the returned offset against exp.
func checkSeek(t *testing.T, ws *ByteBuffer, offset int64, whence, exp int) {
if newOffset, err := ws.Seek(offset, whence); err != nil {
t.Fatalf("Seek(%v, %v) failed: %v", offset, whence, err)
} else if newOffset != int64(exp) {
t.Fatalf("Seek(%v, %v) = %v; want %v", offset, whence, newOffset, exp)
}
func checkSeek(t *testing.T, ws *stream.ByteBuffer, offset int64, whence, exp int) {
newOffset, err := ws.Seek(offset, whence)
require.NoError(t, err)

require.EqualValues(t, exp, newOffset)
}
34 changes: 34 additions & 0 deletions serializer/stream/byte_reader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package stream_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/serializer/v2/stream"
)

func TestByteReaderBytesRead(t *testing.T) {
testCases := []struct {
input []byte
expected int
}{
{[]byte{1, 2, 3, 4, 5}, 0}, // No bytes read initially
{[]byte{1, 2, 3, 4, 5}, 3}, // 3 bytes read after reading 3 bytes
{[]byte{1, 2, 3, 4, 5}, 5}, // All 5 bytes read after reading all bytes
}

for _, tc := range testCases {
bytes := make([]byte, tc.expected)

reader := stream.NewByteReader(tc.input)

nBytes, err := reader.Read(bytes)
require.NoError(t, err)
require.Equal(t, tc.expected, nBytes)

require.Equal(t, tc.input[:tc.expected], bytes[:tc.expected])

require.Equal(t, tc.expected, reader.BytesRead())
}
}
46 changes: 46 additions & 0 deletions serializer/stream/offset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package stream_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/serializer/v2/stream"
)

func TestOffset(t *testing.T) {
buffer := stream.NewByteReader([]byte{1, 2, 3, 4, 5})

offset, err := stream.Offset(buffer)
require.NoError(t, err)
require.EqualValues(t, 0, offset)

{
_, err = buffer.Read([]byte{1})
require.NoError(t, err)

offset, err = stream.Offset(buffer)
require.NoError(t, err)
require.EqualValues(t, 1, offset)
}

{
newOffset, err := stream.Skip(buffer, 3)
require.NoError(t, err)
require.EqualValues(t, 4, newOffset)

offset, err = stream.Offset(buffer)
require.NoError(t, err)
require.EqualValues(t, 4, offset)
}

{
newOffset, err := stream.GoTo(buffer, 2)
require.NoError(t, err)
require.EqualValues(t, 2, newOffset)

offset, err = stream.Offset(buffer)
require.NoError(t, err)
require.EqualValues(t, 2, offset)
}
}
100 changes: 100 additions & 0 deletions serializer/stream/read_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package stream_test

import (
"bytes"
"testing"

"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/serializer/v2"
"github.com/iotaledger/hive.go/serializer/v2/stream"
)

func TestRead(t *testing.T) {
buffer := bytes.NewReader([]byte{42, 0, 0, 0, 0, 0, 0, 0})

result, err := stream.Read[uint64](buffer)

require.NoError(t, err)
require.EqualValues(t, 42, result)
}

func TestReadBytes(t *testing.T) {
initialBytes := []byte{1, 2, 3, 4, 5}
buffer := bytes.NewReader(initialBytes)

readBytes, err := stream.ReadBytes(buffer, 5)
require.NoError(t, err)
require.EqualValues(t, initialBytes, readBytes)
}

func TestReadBytesWithSize(t *testing.T) {
initialBytes := []byte{5, 0, 1, 2, 3, 4, 5}
buffer := bytes.NewReader(initialBytes)

readBytes, err := stream.ReadBytesWithSize(buffer, serializer.SeriLengthPrefixTypeAsUint16)
require.NoError(t, err)

require.EqualValues(t, []byte{1, 2, 3, 4, 5}, readBytes)
}

func TestReadObject(t *testing.T) {
buffer := bytes.NewReader([]byte{42, 0, 57, 5, 0, 0, 0, 0, 0, 0})

result, err := stream.ReadObject(buffer, 10, sampleStructFromBytes)
require.NoError(t, err)

expected := sampleStruct{42, 1337}
require.EqualValues(t, expected, result)
}

func TestReadObjectWithSize(t *testing.T) {
buffer := bytes.NewReader([]byte{10, 0, 42, 0, 57, 5, 0, 0, 0, 0, 0, 0})

result, err := stream.ReadObjectWithSize(buffer, serializer.SeriLengthPrefixTypeAsUint16, sampleStructFromBytes)
require.NoError(t, err)

expected := sampleStruct{42, 1337}
require.EqualValues(t, expected, result)
}

func TestReadObjectFromReader(t *testing.T) {
buffer := bytes.NewReader([]byte{42, 0, 57, 5, 0, 0, 0, 0, 0, 0})

result, err := stream.ReadObjectFromReader(buffer, sampleStructFromReader)
require.NoError(t, err)

expected := sampleStruct{42, 1337}
require.EqualValues(t, expected, result)
}

func TestPeek(t *testing.T) {
buffer := bytes.NewReader([]byte{3, 0, 0, 0, 1, 0, 2, 0, 3, 0})

elementsCount, err := stream.Peek(buffer, serializer.SeriLengthPrefixTypeAsUint32)
require.NoError(t, err)
require.EqualValues(t, 3, elementsCount)
}

func TestReadCollection(t *testing.T) {
buffer := bytes.NewReader([]byte{3, 0, 0, 0, 1, 0, 2, 0, 3, 0})

count, err := stream.Peek(buffer, serializer.SeriLengthPrefixTypeAsUint32)
require.NoError(t, err)
require.EqualValues(t, 3, count)

results := make([]uint16, count)

err = stream.ReadCollection(buffer, serializer.SeriLengthPrefixTypeAsUint32, func(i int) error {
result, err := stream.Read[uint16](buffer)
require.NoError(t, err)

results[i] = result

return nil
})
require.NoError(t, err)

expected := []uint16{1, 2, 3}
require.EqualValues(t, expected, results)
}
125 changes: 125 additions & 0 deletions serializer/stream/write_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package stream_test

import (
"encoding/binary"
"io"
"testing"

"github.com/stretchr/testify/require"

"github.com/iotaledger/hive.go/lo"
"github.com/iotaledger/hive.go/serializer/v2"
"github.com/iotaledger/hive.go/serializer/v2/byteutils"
"github.com/iotaledger/hive.go/serializer/v2/stream"
)

func requireBufferBytes(t *testing.T, buffer *stream.ByteBuffer, expected []byte) {
bytesInBuffer, err := buffer.Bytes()
require.NoError(t, err)

require.Equal(t, expected, bytesInBuffer)
}

type sampleStruct struct {
Value0 uint16
Value1 uint64
}

func (s sampleStruct) Bytes() ([]byte, error) {
bytes := make([]byte, 10)
binary.LittleEndian.PutUint16(bytes[:2], s.Value0)
binary.LittleEndian.PutUint64(bytes[2:], s.Value1)

return bytes, nil
}

func sampleStructFromBytes(bytes []byte) (sampleStruct, int, error) {
value0 := binary.LittleEndian.Uint16(bytes[:2])
value1 := binary.LittleEndian.Uint64(bytes[2:])

return sampleStruct{value0, value1}, 10, nil
}

func sampleStructFromReader(reader io.ReadSeeker) (sampleStruct, error) {
bytes := make([]byte, 10)
_, err := reader.Read(bytes)
if err != nil {
return sampleStruct{}, err
}

value0 := binary.LittleEndian.Uint16(bytes[:2])
value1 := binary.LittleEndian.Uint64(bytes[2:])

return sampleStruct{value0, value1}, nil
}

func TestWrite(t *testing.T) {
buffer := stream.NewByteBuffer()

err := stream.Write(buffer, uint64(42))
require.NoError(t, err)

expected := []byte{42, 0, 0, 0, 0, 0, 0, 0}
requireBufferBytes(t, buffer, expected)
}

func TestWriteBytes(t *testing.T) {
buffer := stream.NewByteBuffer()
bytesToWrite := []byte{1, 2, 3, 4, 5}

err := stream.WriteBytes(buffer, bytesToWrite)
require.NoError(t, err)

requireBufferBytes(t, buffer, bytesToWrite)
}

func TestWriteBytesWithSize(t *testing.T) {
buffer := stream.NewByteBuffer()
bytesToWrite := []byte{1, 2, 3, 4, 5}

err := stream.WriteBytesWithSize(buffer, bytesToWrite, serializer.SeriLengthPrefixTypeAsUint16)
require.NoError(t, err)

expected := []byte{5, 0, 1, 2, 3, 4, 5}
requireBufferBytes(t, buffer, expected)
}

func TestWriteObject(t *testing.T) {
buffer := stream.NewByteBuffer()

s := sampleStruct{42, 1337}
err := stream.WriteObject(buffer, s, sampleStruct.Bytes)
require.NoError(t, err)

expected := lo.PanicOnErr(s.Bytes())
requireBufferBytes(t, buffer, expected)
}

func TestWriteObjectWithSize(t *testing.T) {
buffer := stream.NewByteBuffer()

s := sampleStruct{42, 1337}
err := stream.WriteObjectWithSize(buffer, s, serializer.SeriLengthPrefixTypeAsUint16, sampleStruct.Bytes)
require.NoError(t, err)

expected := byteutils.ConcatBytes([]byte{10, 0}, lo.PanicOnErr(s.Bytes()))
requireBufferBytes(t, buffer, expected)
}

func TestWriteCollection(t *testing.T) {
buffer := stream.NewByteBuffer()

elementsCount := 3
err := stream.WriteCollection(buffer, serializer.SeriLengthPrefixTypeAsUint32, func() (int, error) {
for i := 0; i < elementsCount; i++ {
if err := stream.Write(buffer, uint16(i+1)); err != nil {
return 0, err
}
}
return elementsCount, nil
})
require.NoError(t, err)

expected := []byte{3, 0, 0, 0, 1, 0, 2, 0, 3, 0}
requireBufferBytes(t, buffer, expected)
}

0 comments on commit 2659fb1

Please sign in to comment.