blob: 09b2546227a5c247db70801f793963dcac86e0a1 [file] [log] [blame]
package bencode
import (
"reflect"
"testing"
)
func TestDecode(t *testing.T) {
type testCase struct {
in string
val interface{}
expect interface{}
err bool
}
type dT struct {
X string
Y int
Z string `bencode:"zff"`
}
var decodeCases = []testCase{
//integers
{`i5e`, new(int), int(5), false},
{`i-10e`, new(int), int(-10), false},
{`i8e`, new(uint), uint(8), false},
{`i8e`, new(uint8), uint8(8), false},
{`i8e`, new(uint16), uint16(8), false},
{`i8e`, new(uint32), uint32(8), false},
{`i8e`, new(uint64), uint64(8), false},
{`i8e`, new(int), int(8), false},
{`i8e`, new(int8), int8(8), false},
{`i8e`, new(int16), int16(8), false},
{`i8e`, new(int32), int32(8), false},
{`i8e`, new(int64), int64(8), false},
{`i-2e`, new(uint), nil, true},
//bools
{`i1e`, new(bool), true, false},
{`i0e`, new(bool), false, false},
{`i8e`, new(bool), true, false},
//strings
{`3:foo`, new(string), "foo", false},
{`4:foob`, new(string), "foob", false},
{`6:short`, new(string), nil, true},
//lists
{`l3:foo3:bare`, new([]string), []string{"foo", "bar"}, false},
{`li15ei20ee`, new([]int), []int{15, 20}, false},
{`ld3:fooi0eed3:bari1eee`, new([]map[string]int), []map[string]int{
{"foo": 0},
{"bar": 1},
}, false},
//dicts
{`d3:foo3:bar4:foob3:fooe`, new(map[string]string), map[string]string{
"foo": "bar",
"foob": "foo",
}, false},
{`d1:X3:foo1:Yi10e3:zff3:bare`, new(dT), dT{"foo", 10, "bar"}, false},
{`d1:X3:foo1:Yi10e1:Z3:bare`, new(dT), dT{"foo", 10, "bar"}, false},
{`d1:X3:foo1:Yi10e1:h3:bare`, new(dT), dT{"foo", 10, ""}, false},
{`d3:fooli0ei1ee3:barli2ei3eee`, new(map[string][]int), map[string][]int{
"foo": []int{0, 1},
"bar": []int{2, 3},
}, false},
{`de`, new(map[string]string), map[string]string{}, false},
//into interfaces
{`i5e`, new(interface{}), int64(5), false},
{`li5ee`, new(interface{}), []interface{}{int64(5)}, false},
{`5:hello`, new(interface{}), "hello", false},
{`d5:helloi5ee`, new(interface{}), map[string]interface{}{"hello": int64(5)}, false},
//malformed
{`i53:foo`, new(interface{}), nil, true},
{`6:foo`, new(interface{}), nil, true},
{`di5ei2ee`, new(interface{}), nil, true},
{`d3:fooe`, new(interface{}), nil, true},
{`l3:foo3:bar`, new(interface{}), nil, true},
{`d-1:`, new(interface{}), nil, true},
}
for i, tt := range decodeCases {
err := DecodeString(tt.in, tt.val)
if !tt.err && err != nil {
t.Errorf("#%d: Unexpected err: %v", i, err)
continue
}
if tt.err && err == nil {
t.Errorf("#%d: Expected err is nil", i)
continue
}
v := reflect.ValueOf(tt.val).Elem().Interface()
if !reflect.DeepEqual(v, tt.expect) && !tt.err {
t.Errorf("#%d: Val: %#v != %#v", i, v, tt.expect)
}
}
}
func TestRawDecode(t *testing.T) {
type testCase struct {
in string
expect []byte
err bool
}
var rawDecodeCases = []testCase{
{`i5e`, []byte(`i5e`), false},
{`5:hello`, []byte(`5:hello`), false},
{`li5ei10e5:helloe`, []byte(`li5ei10e5:helloe`), false},
{`llleee`, []byte(`llleee`), false},
{`li5eli5eli5eeee`, []byte(`li5eli5eli5eeee`), false},
{`d5:helloi5ee`, []byte(`d5:helloi5ee`), false},
}
for i, tt := range rawDecodeCases {
var x RawMessage
err := DecodeString(tt.in, &x)
if !tt.err && err != nil {
t.Errorf("#%d: Unexpected err: %v", i, err)
continue
}
if tt.err && err == nil {
t.Errorf("#%d: Expected err is nil", i)
continue
}
if !reflect.DeepEqual(x, RawMessage(tt.expect)) && !tt.err {
t.Errorf("#%d: Val: %#v != %#v", i, x, tt.expect)
}
}
}
func TestNestedRawDecode(t *testing.T) {
type testCase struct {
in string
val interface{}
expect interface{}
err bool
}
type message struct {
Key string
Val int
Raw RawMessage
}
var cases = []testCase{
{`li5e5:hellod1:a1:beli5eee`, new([]RawMessage), []RawMessage{
RawMessage(`i5e`),
RawMessage(`5:hello`),
RawMessage(`d1:a1:be`),
RawMessage(`li5ee`),
}, false},
{`d1:a1:b1:c1:de`, new(map[string]RawMessage), map[string]RawMessage{
"a": RawMessage(`1:b`),
"c": RawMessage(`1:d`),
}, false},
{`d3:Key5:hello3:Rawldedei5e1:ae3:Vali10ee`, new(message), message{
Key: "hello",
Val: 10,
Raw: RawMessage(`ldedei5e1:ae`),
}, false},
}
for i, tt := range cases {
err := DecodeString(tt.in, tt.val)
if !tt.err && err != nil {
t.Errorf("#%d: Unexpected err: %v", i, err)
continue
}
if tt.err && err == nil {
t.Errorf("#%d: Expected err is nil", i)
continue
}
v := reflect.ValueOf(tt.val).Elem().Interface()
if !reflect.DeepEqual(v, tt.expect) && !tt.err {
t.Errorf("#%d: Val:\n%#v !=\n%#v", i, v, tt.expect)
}
}
}