mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-23 09:18:51 +02:00
feat: implement experimental BackScanner for reading files backward and add tests for various scenarios
This commit is contained in:
127
internal/net/gphttp/accesslog/back_scanner_test.go
Normal file
127
internal/net/gphttp/accesslog/back_scanner_test.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package accesslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBackScanner(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "empty file",
|
||||
input: "",
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
name: "single line without newline",
|
||||
input: "single line",
|
||||
expected: []string{"single line"},
|
||||
},
|
||||
{
|
||||
name: "single line with newline",
|
||||
input: "single line\n",
|
||||
expected: []string{"single line"},
|
||||
},
|
||||
{
|
||||
name: "multiple lines",
|
||||
input: "first\nsecond\nthird\n",
|
||||
expected: []string{"third", "second", "first"},
|
||||
},
|
||||
{
|
||||
name: "multiple lines without final newline",
|
||||
input: "first\nsecond\nthird",
|
||||
expected: []string{"third", "second", "first"},
|
||||
},
|
||||
{
|
||||
name: "lines longer than chunk size",
|
||||
input: "short\n" + strings.Repeat("a", 20) + "\nshort\n",
|
||||
expected: []string{"short", strings.Repeat("a", 20), "short"},
|
||||
},
|
||||
{
|
||||
name: "empty lines",
|
||||
input: "first\n\n\nlast\n",
|
||||
expected: []string{"last", "first"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Setup mock file
|
||||
mockFile := &MockFile{}
|
||||
_, err := mockFile.Write([]byte(tt.input))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write to mock file: %v", err)
|
||||
}
|
||||
|
||||
// Create scanner with small chunk size to test chunking
|
||||
scanner := NewBackScanner(mockFile, 10)
|
||||
|
||||
// Collect all lines
|
||||
var lines [][]byte
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Bytes())
|
||||
}
|
||||
|
||||
// Check for scanning errors
|
||||
if err := scanner.Err(); err != nil {
|
||||
t.Errorf("scanner error: %v", err)
|
||||
}
|
||||
|
||||
// Compare results
|
||||
if len(lines) != len(tt.expected) {
|
||||
t.Errorf("got %d lines, want %d lines", len(lines), len(tt.expected))
|
||||
return
|
||||
}
|
||||
|
||||
for i, line := range lines {
|
||||
if string(line) != tt.expected[i] {
|
||||
t.Errorf("line %d: got %q, want %q", i, line, tt.expected[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackScannerWithVaryingChunkSizes(t *testing.T) {
|
||||
input := "first\nsecond\nthird\nfourth\nfifth\n"
|
||||
expected := []string{"fifth", "fourth", "third", "second", "first"}
|
||||
chunkSizes := []int{1, 2, 3, 5, 10, 20, 100}
|
||||
|
||||
for _, chunkSize := range chunkSizes {
|
||||
t.Run(fmt.Sprintf("chunk_size_%d", chunkSize), func(t *testing.T) {
|
||||
mockFile := &MockFile{}
|
||||
_, err := mockFile.Write([]byte(input))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write to mock file: %v", err)
|
||||
}
|
||||
|
||||
scanner := NewBackScanner(mockFile, chunkSize)
|
||||
|
||||
var lines [][]byte
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Bytes())
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
t.Errorf("scanner error: %v", err)
|
||||
}
|
||||
|
||||
if len(lines) != len(expected) {
|
||||
t.Errorf("got %d lines, want %d lines", len(lines), len(expected))
|
||||
return
|
||||
}
|
||||
|
||||
for i, line := range lines {
|
||||
if string(line) != expected[i] {
|
||||
t.Errorf("chunk size %d, line %d: got %q, want %q",
|
||||
chunkSize, i, line, expected[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user