mirror of
https://github.com/bluekeyes/go-gitdiff
synced 2026-06-08 13:18:30 +00:00
09f3004fce
copyFrom and copyLinesFrom did not increment the start offset after reading, so the same lines were copied over and over again.
203 lines
4.2 KiB
Go
203 lines
4.2 KiB
Go
package gitdiff
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"math/rand"
|
|
"testing"
|
|
)
|
|
|
|
func TestLineReaderAt(t *testing.T) {
|
|
tests := map[string]struct {
|
|
InputLines int
|
|
Offset int64
|
|
Count int
|
|
Err bool
|
|
EOF bool
|
|
EOFCount int
|
|
}{
|
|
"readLines": {
|
|
InputLines: 32,
|
|
Offset: 0,
|
|
Count: 4,
|
|
},
|
|
"readLinesOffset": {
|
|
InputLines: 32,
|
|
Offset: 8,
|
|
Count: 4,
|
|
},
|
|
"readLinesLargeOffset": {
|
|
InputLines: 8192,
|
|
Offset: 4096,
|
|
Count: 64,
|
|
},
|
|
"readSingleLine": {
|
|
InputLines: 4,
|
|
Offset: 2,
|
|
Count: 1,
|
|
},
|
|
"readZeroLines": {
|
|
InputLines: 4,
|
|
Offset: 2,
|
|
Count: 0,
|
|
},
|
|
"readThroughEOF": {
|
|
InputLines: 16,
|
|
Offset: 12,
|
|
Count: 8,
|
|
EOF: true,
|
|
EOFCount: 4,
|
|
},
|
|
"emptyInput": {
|
|
InputLines: 0,
|
|
Offset: 0,
|
|
Count: 2,
|
|
EOF: true,
|
|
EOFCount: 0,
|
|
},
|
|
"offsetAfterEOF": {
|
|
InputLines: 8,
|
|
Offset: 10,
|
|
Count: 2,
|
|
EOF: true,
|
|
EOFCount: 0,
|
|
},
|
|
"offsetNegative": {
|
|
InputLines: 8,
|
|
Offset: -1,
|
|
Count: 2,
|
|
Err: true,
|
|
},
|
|
}
|
|
|
|
const lineTemplate = "generated test line %d\n"
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
var input bytes.Buffer
|
|
for i := 0; i < test.InputLines; i++ {
|
|
fmt.Fprintf(&input, lineTemplate, i)
|
|
}
|
|
|
|
output := make([][]byte, test.Count)
|
|
for i := 0; i < test.Count; i++ {
|
|
output[i] = []byte(fmt.Sprintf(lineTemplate, test.Offset+int64(i)))
|
|
}
|
|
|
|
r := &lineReaderAt{r: bytes.NewReader(input.Bytes())}
|
|
lines := make([][]byte, test.Count)
|
|
|
|
n, err := r.ReadLinesAt(lines, test.Offset)
|
|
if test.Err {
|
|
if err == nil {
|
|
t.Fatal("expected error reading lines, but got nil")
|
|
}
|
|
return
|
|
}
|
|
if err != nil && (!test.EOF || err != io.EOF) {
|
|
t.Fatalf("unexpected error reading lines: %v", err)
|
|
}
|
|
|
|
count := test.Count
|
|
if test.EOF {
|
|
count = test.EOFCount
|
|
}
|
|
|
|
if n != count {
|
|
t.Fatalf("incorrect number of lines read: expected %d, actual %d", count, n)
|
|
}
|
|
for i := 0; i < n; i++ {
|
|
if !bytes.Equal(output[i], lines[i]) {
|
|
t.Errorf("incorrect content in line %d:\nexpected: %q\nactual: %q", i, output[i], lines[i])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyFrom(t *testing.T) {
|
|
tests := map[string]struct {
|
|
Bytes int64
|
|
Offset int64
|
|
}{
|
|
"copyAll": {
|
|
Bytes: byteBufferSize / 2,
|
|
},
|
|
"copyPartial": {
|
|
Bytes: byteBufferSize / 2,
|
|
Offset: byteBufferSize / 4,
|
|
},
|
|
"copyLarge": {
|
|
Bytes: 8 * byteBufferSize,
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
data := make([]byte, test.Bytes)
|
|
rand.Read(data)
|
|
|
|
var dst bytes.Buffer
|
|
n, err := copyFrom(&dst, bytes.NewReader(data), test.Offset)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error copying data: %v", err)
|
|
}
|
|
if n != test.Bytes-test.Offset {
|
|
t.Fatalf("incorrect number of bytes copied: expected %d, actual %d", test.Bytes-test.Offset, n)
|
|
}
|
|
|
|
expected := data[test.Offset:]
|
|
if !bytes.Equal(expected, dst.Bytes()) {
|
|
t.Fatalf("incorrect data copied:\nexpected: %v\nactual: %v", expected, dst.Bytes())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyLinesFrom(t *testing.T) {
|
|
tests := map[string]struct {
|
|
Lines int64
|
|
Offset int64
|
|
}{
|
|
"copyAll": {
|
|
Lines: lineBufferSize / 2,
|
|
},
|
|
"copyPartial": {
|
|
Lines: lineBufferSize / 2,
|
|
Offset: lineBufferSize / 4,
|
|
},
|
|
"copyLarge": {
|
|
Lines: 8 * lineBufferSize,
|
|
},
|
|
}
|
|
|
|
const lineLength = 128
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
data := make([]byte, test.Lines*lineLength)
|
|
for i := range data {
|
|
data[i] = byte(32 + rand.Intn(95)) // ascii letters, numbers, symbols
|
|
if i%lineLength == lineLength-1 {
|
|
data[i] = '\n'
|
|
}
|
|
}
|
|
|
|
var dst bytes.Buffer
|
|
n, err := copyLinesFrom(&dst, &lineReaderAt{r: bytes.NewReader(data)}, test.Offset)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error copying data: %v", err)
|
|
}
|
|
if n != test.Lines-test.Offset {
|
|
t.Fatalf("incorrect number of lines copied: expected %d, actual %d", test.Lines-test.Offset, n)
|
|
}
|
|
|
|
expected := data[test.Offset*lineLength:]
|
|
if !bytes.Equal(expected, dst.Bytes()) {
|
|
t.Fatalf("incorrect data copied:\nexpected: %v\nactual: %v", expected, dst.Bytes())
|
|
}
|
|
})
|
|
}
|
|
}
|