]> Sergey Matveev's repositories - btrtrc.git/blob - bencode/decode_test.go
bencode: Encode arrays of bytes as strings
[btrtrc.git] / bencode / decode_test.go
1 package bencode
2
3 import (
4         "bytes"
5         "io"
6         "math/big"
7         "reflect"
8         "testing"
9
10         qt "github.com/frankban/quicktest"
11         "github.com/stretchr/testify/assert"
12         "github.com/stretchr/testify/require"
13 )
14
15 type random_decode_test struct {
16         data     string
17         expected interface{}
18 }
19
20 var random_decode_tests = []random_decode_test{
21         {"i57e", int64(57)},
22         {"i-9223372036854775808e", int64(-9223372036854775808)},
23         {"5:hello", "hello"},
24         {"29:unicode test проверка", "unicode test проверка"},
25         {"d1:ai5e1:b5:helloe", map[string]interface{}{"a": int64(5), "b": "hello"}},
26         {"li5ei10ei15ei20e7:bencodee",
27                 []interface{}{int64(5), int64(10), int64(15), int64(20), "bencode"}},
28         {"ldedee", []interface{}{map[string]interface{}{}, map[string]interface{}{}}},
29         {"le", []interface{}{}},
30         {"i604919719469385652980544193299329427705624352086e", func() *big.Int {
31                 ret, _ := big.NewInt(-1).SetString("604919719469385652980544193299329427705624352086", 10)
32                 return ret
33         }()},
34         {"d1:rd6:\xd4/\xe2F\x00\x01e1:t3:\x9a\x87\x011:v4:TR%=1:y1:re", map[string]interface{}{
35                 "r": map[string]interface{}{},
36                 "t": "\x9a\x87\x01",
37                 "v": "TR%=",
38                 "y": "r",
39         }},
40 }
41
42 func TestRandomDecode(t *testing.T) {
43         for _, test := range random_decode_tests {
44                 var value interface{}
45                 err := Unmarshal([]byte(test.data), &value)
46                 if err != nil {
47                         t.Error(err, test.data)
48                         continue
49                 }
50                 assert.EqualValues(t, test.expected, value)
51         }
52 }
53
54 func TestLoneE(t *testing.T) {
55         var v int
56         err := Unmarshal([]byte("e"), &v)
57         se := err.(*SyntaxError)
58         require.EqualValues(t, 0, se.Offset)
59 }
60
61 func TestDecoderConsecutive(t *testing.T) {
62         d := NewDecoder(bytes.NewReader([]byte("i1ei2e")))
63         var i int
64         err := d.Decode(&i)
65         require.NoError(t, err)
66         require.EqualValues(t, 1, i)
67         err = d.Decode(&i)
68         require.NoError(t, err)
69         require.EqualValues(t, 2, i)
70         err = d.Decode(&i)
71         require.Equal(t, io.EOF, err)
72 }
73
74 func TestDecoderConsecutiveDicts(t *testing.T) {
75         bb := bytes.NewBufferString("d4:herp4:derped3:wat1:ke17:oh baby a triple!")
76
77         d := NewDecoder(bb)
78         assert.EqualValues(t, "d4:herp4:derped3:wat1:ke17:oh baby a triple!", bb.Bytes())
79         assert.EqualValues(t, 0, d.Offset)
80
81         var m map[string]interface{}
82
83         require.NoError(t, d.Decode(&m))
84         assert.Len(t, m, 1)
85         assert.Equal(t, "derp", m["herp"])
86         assert.Equal(t, "d3:wat1:ke17:oh baby a triple!", bb.String())
87         assert.EqualValues(t, 14, d.Offset)
88
89         require.NoError(t, d.Decode(&m))
90         assert.Equal(t, "k", m["wat"])
91         assert.Equal(t, "17:oh baby a triple!", bb.String())
92         assert.EqualValues(t, 24, d.Offset)
93
94         var s string
95         require.NoError(t, d.Decode(&s))
96         assert.Equal(t, "oh baby a triple!", s)
97         assert.EqualValues(t, 44, d.Offset)
98 }
99
100 func check_error(t *testing.T, err error) {
101         if err != nil {
102                 t.Error(err)
103         }
104 }
105
106 func assert_equal(t *testing.T, x, y interface{}) {
107         if !reflect.DeepEqual(x, y) {
108                 t.Errorf("got: %v (%T), expected: %v (%T)\n", x, x, y, y)
109         }
110 }
111
112 type unmarshalerInt struct {
113         x int
114 }
115
116 func (me *unmarshalerInt) UnmarshalBencode(data []byte) error {
117         return Unmarshal(data, &me.x)
118 }
119
120 type unmarshalerString struct {
121         x string
122 }
123
124 func (me *unmarshalerString) UnmarshalBencode(data []byte) error {
125         me.x = string(data)
126         return nil
127 }
128
129 func TestUnmarshalerBencode(t *testing.T) {
130         var i unmarshalerInt
131         var ss []unmarshalerString
132         check_error(t, Unmarshal([]byte("i71e"), &i))
133         assert_equal(t, i.x, 71)
134         check_error(t, Unmarshal([]byte("l5:hello5:fruit3:waye"), &ss))
135         assert_equal(t, ss[0].x, "5:hello")
136         assert_equal(t, ss[1].x, "5:fruit")
137         assert_equal(t, ss[2].x, "3:way")
138
139 }
140
141 func TestIgnoreUnmarshalTypeError(t *testing.T) {
142         s := struct {
143                 Ignore int `bencode:",ignore_unmarshal_type_error"`
144                 Normal int
145         }{}
146         require.Error(t, Unmarshal([]byte("d6:Normal5:helloe"), &s))
147         assert.NoError(t, Unmarshal([]byte("d6:Ignore5:helloe"), &s))
148         qt.Assert(t, Unmarshal([]byte("d6:Ignorei42ee"), &s), qt.IsNil)
149         assert.EqualValues(t, 42, s.Ignore)
150 }
151
152 // Test unmarshalling []byte into something that has the same kind but
153 // different type.
154 func TestDecodeCustomSlice(t *testing.T) {
155         type flag byte
156         var fs3, fs2 []flag
157         // We do a longer slice then a shorter slice to see if the buffers are
158         // shared.
159         d := NewDecoder(bytes.NewBufferString("3:\x01\x10\xff2:\x04\x0f"))
160         require.NoError(t, d.Decode(&fs3))
161         require.NoError(t, d.Decode(&fs2))
162         assert.EqualValues(t, []flag{1, 16, 255}, fs3)
163         assert.EqualValues(t, []flag{4, 15}, fs2)
164 }
165
166 func TestUnmarshalUnusedBytes(t *testing.T) {
167         var i int
168         require.EqualValues(t, ErrUnusedTrailingBytes{1}, Unmarshal([]byte("i42ee"), &i))
169         assert.EqualValues(t, 42, i)
170 }
171
172 func TestUnmarshalByteArray(t *testing.T) {
173         var ba [2]byte
174         assert.NoError(t, Unmarshal([]byte("2:hi"), &ba))
175         assert.EqualValues(t, "hi", ba[:])
176 }
177
178 func TestDecodeDictIntoUnsupported(t *testing.T) {
179         // Any type that a dict shouldn't be unmarshallable into.
180         var i int
181         c := qt.New(t)
182         err := Unmarshal([]byte("d1:a1:be"), &i)
183         t.Log(err)
184         c.Check(err, qt.Not(qt.IsNil))
185 }
186
187 func TestUnmarshalDictKeyNotString(t *testing.T) {
188         // Any type that a dict shouldn't be unmarshallable into.
189         var i int
190         c := qt.New(t)
191         err := Unmarshal([]byte("di42e3:yese"), &i)
192         t.Log(err)
193         c.Check(err, qt.Not(qt.IsNil))
194 }