github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/internal/buffered_seek_reader_test.go (about)

     1  package internal
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestBufferedSeeker_Read(t *testing.T) {
    13  	tests := []struct {
    14  		name          string
    15  		initialData   string
    16  		readLengths   []int
    17  		expectedReads []string
    18  		expectError   bool
    19  	}{
    20  		{
    21  			name:          "go case (read)",
    22  			initialData:   "Hello, World!",
    23  			readLengths:   []int{5},
    24  			expectedReads: []string{"Hello"},
    25  		},
    26  		{
    27  			name:          "multiple reads",
    28  			initialData:   "Hello, World!",
    29  			readLengths:   []int{5, 8},
    30  			expectedReads: []string{"Hello", ", World!"},
    31  		},
    32  	}
    33  
    34  	for _, tt := range tests {
    35  		t.Run(tt.name, func(t *testing.T) {
    36  			bs := NewBufferedSeeker(io.NopCloser(bytes.NewBufferString(tt.initialData)))
    37  
    38  			for i, length := range tt.readLengths {
    39  				buf := make([]byte, length)
    40  				n, err := bs.Read(buf)
    41  
    42  				if !tt.expectError {
    43  					assert.NoError(t, err)
    44  					assert.Equalf(t, tt.expectedReads[i], string(buf[:n]), "read index %d", i)
    45  				} else {
    46  					assert.Error(t, err)
    47  				}
    48  			}
    49  		})
    50  	}
    51  }
    52  
    53  func TestBufferedSeeker_Seek(t *testing.T) {
    54  	tests := []struct {
    55  		name          string
    56  		initialData   string
    57  		readLengths   []int
    58  		seekOffsets   []int64
    59  		seekWhence    []int
    60  		expectedReads []string
    61  		seekError     require.ErrorAssertionFunc
    62  		readError     require.ErrorAssertionFunc
    63  	}{
    64  		{
    65  			name:          "seek start 0 without read first",
    66  			initialData:   "Hello, World!",
    67  			readLengths:   []int{5},
    68  			seekOffsets:   []int64{0},
    69  			seekWhence:    []int{io.SeekStart},
    70  			expectedReads: []string{"Hello"},
    71  		},
    72  		{
    73  			name:          "read + seek back",
    74  			initialData:   "Hello, World!",
    75  			readLengths:   []int{5, 8, 8},
    76  			seekOffsets:   []int64{-1, -1, 2},
    77  			seekWhence:    []int{io.SeekStart, io.SeekStart, io.SeekStart},
    78  			expectedReads: []string{"Hello", ", World!", "llo, Wor"},
    79  		},
    80  		{
    81  			name:          "seek past read data",
    82  			initialData:   "Hello, World!",
    83  			readLengths:   []int{5},
    84  			seekOffsets:   []int64{20},
    85  			seekWhence:    []int{io.SeekStart},
    86  			expectedReads: []string{""},
    87  			seekError:     require.Error,
    88  		},
    89  		{
    90  			name:          "seek to end",
    91  			initialData:   "Hello, World!",
    92  			readLengths:   []int{-1},
    93  			seekOffsets:   []int64{20},
    94  			seekWhence:    []int{io.SeekEnd},
    95  			expectedReads: []string{""},
    96  			seekError:     require.Error,
    97  		},
    98  	}
    99  
   100  	for _, tt := range tests {
   101  		t.Run(tt.name, func(t *testing.T) {
   102  			if tt.seekError == nil {
   103  				tt.seekError = require.NoError
   104  			}
   105  			if tt.readError == nil {
   106  				tt.readError = require.NoError
   107  			}
   108  
   109  			bs := NewBufferedSeeker(io.NopCloser(bytes.NewBufferString(tt.initialData)))
   110  
   111  			for i, length := range tt.readLengths {
   112  				if len(tt.seekOffsets) > i && tt.seekOffsets[i] >= 0 {
   113  					_, err := bs.Seek(tt.seekOffsets[i], tt.seekWhence[i])
   114  					tt.seekError(t, err)
   115  					if err != nil {
   116  						continue
   117  					}
   118  				}
   119  
   120  				if length >= 0 {
   121  					buf := make([]byte, length)
   122  					n, err := bs.Read(buf)
   123  					tt.readError(t, err)
   124  					if err != nil {
   125  						continue
   126  					}
   127  					assert.Equalf(t, tt.expectedReads[i], string(buf[:n]), "read index %d", i)
   128  				}
   129  			}
   130  		})
   131  	}
   132  }
   133  
   134  func TestBufferedSeeker_Close(t *testing.T) {
   135  	bs := NewBufferedSeeker(io.NopCloser(bytes.NewBufferString("Hello, World!")))
   136  	err := bs.Close()
   137  	assert.NoError(t, err)
   138  	n, err := bs.Read(make([]byte, 1))
   139  	assert.Equal(t, 0, n)
   140  	assert.Error(t, err)
   141  }