142 lines
3.0 KiB
Go
142 lines
3.0 KiB
Go
package metainfo
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"testing"
|
|
|
|
"storrent/bencode"
|
|
)
|
|
|
|
func TestParse(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
info map[string]any
|
|
wantName string
|
|
wantSize int64
|
|
}{
|
|
{
|
|
name: "single file",
|
|
info: map[string]any{
|
|
"name": "test.txt",
|
|
"piece length": int64(16384),
|
|
"pieces": string(make([]byte, 20)),
|
|
"length": int64(100),
|
|
},
|
|
wantName: "test.txt",
|
|
wantSize: 100,
|
|
},
|
|
{
|
|
name: "multi file",
|
|
info: map[string]any{
|
|
"name": "dir",
|
|
"piece length": int64(16384),
|
|
"pieces": string(make([]byte, 20)),
|
|
"files": []any{
|
|
map[string]any{"length": int64(100), "path": []any{"a.txt"}},
|
|
map[string]any{"length": int64(200), "path": []any{"b.txt"}},
|
|
},
|
|
},
|
|
wantName: "dir",
|
|
wantSize: 300,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data, err := bencode.Encode(map[string]any{"info": tt.info})
|
|
if err != nil {
|
|
t.Fatalf("Encode: %v", err)
|
|
}
|
|
m, err := ParseBytes(data)
|
|
if err != nil {
|
|
t.Fatalf("ParseBytes: %v", err)
|
|
}
|
|
if m.Info.Name != tt.wantName {
|
|
t.Errorf("Name: got %s, want %s", m.Info.Name, tt.wantName)
|
|
}
|
|
if m.Size != tt.wantSize {
|
|
t.Errorf("Size: got %d, want %d", m.Size, tt.wantSize)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestInfoHash(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
raw string
|
|
}{
|
|
{
|
|
name: "basic",
|
|
raw: "d6:lengthi1e4:name4:test12:piece lengthi16384e6:pieces20:01234567890123456789e",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
raw := []byte(tt.raw)
|
|
torrent := append([]byte("d4:info"), raw...)
|
|
torrent = append(torrent, 'e')
|
|
m, err := ParseBytes(torrent)
|
|
if err != nil {
|
|
t.Fatalf("ParseBytes: %v", err)
|
|
}
|
|
want := sha1.Sum(raw)
|
|
if m.InfoHash != want {
|
|
t.Errorf("InfoHash: got %x, want %x", m.InfoHash, want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSegments(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
files []Entry
|
|
off int64
|
|
size int64
|
|
want []Segment
|
|
}{
|
|
{
|
|
name: "single file",
|
|
files: []Entry{{Size: 32, Offset: 0}},
|
|
off: 0,
|
|
size: 32,
|
|
want: []Segment{{0, 0, 32}},
|
|
},
|
|
{
|
|
name: "spans two files",
|
|
files: []Entry{{Size: 16, Offset: 0}, {Size: 16, Offset: 16}},
|
|
off: 0,
|
|
size: 32,
|
|
want: []Segment{{0, 0, 16}, {1, 0, 16}},
|
|
},
|
|
{
|
|
name: "middle of file",
|
|
files: []Entry{{Size: 32, Offset: 0}},
|
|
off: 8,
|
|
size: 16,
|
|
want: []Segment{{0, 8, 16}},
|
|
},
|
|
{
|
|
name: "skip first file",
|
|
files: []Entry{{Size: 16, Offset: 0}, {Size: 16, Offset: 16}},
|
|
off: 16,
|
|
size: 16,
|
|
want: []Segment{{1, 0, 16}},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
info := Info{Files: tt.files}
|
|
got := info.Segments(tt.off, tt.size)
|
|
if len(got) != len(tt.want) {
|
|
t.Fatalf("got %d segments, want %d", len(got), len(tt.want))
|
|
}
|
|
for i := range got {
|
|
if got[i] != tt.want[i] {
|
|
t.Errorf("segment %d: got %+v, want %+v", i, got[i], tt.want[i])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|