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 }