2017-05-06 13:43:24 +02:00
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 {
2017-05-24 09:15:07 +02:00
"foo" : { 0 , 1 } ,
"bar" : { 2 , 3 } ,
2017-05-06 13:43:24 +02:00
} , 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 )
}
}
}