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