added support for string type
[govpp.git] / vendor / github.com / lunixbochs / struc / struc_test.go
1 package struc
2
3 import (
4         "bytes"
5         "encoding/binary"
6         "reflect"
7         "testing"
8 )
9
10 type Nested struct {
11         Test2 int `struc:"int8"`
12 }
13
14 type Example struct {
15         Pad    []byte `struc:"[5]pad"`        // 00 00 00 00 00
16         I8f    int    `struc:"int8"`          // 01
17         I16f   int    `struc:"int16"`         // 00 02
18         I32f   int    `struc:"int32"`         // 00 00 00 03
19         I64f   int    `struc:"int64"`         // 00 00 00 00 00 00 00 04
20         U8f    int    `struc:"uint8,little"`  // 05
21         U16f   int    `struc:"uint16,little"` // 06 00
22         U32f   int    `struc:"uint32,little"` // 07 00 00 00
23         U64f   int    `struc:"uint64,little"` // 08 00 00 00 00 00 00 00
24         Boolf  int    `struc:"bool"`          // 01
25         Byte4f []byte `struc:"[4]byte"`       // "abcd"
26
27         I8     int8    // 09
28         I16    int16   // 00 0a
29         I32    int32   // 00 00 00 0b
30         I64    int64   // 00 00 00 00 00 00 00 0c
31         U8     uint8   `struc:"little"` // 0d
32         U16    uint16  `struc:"little"` // 0e 00
33         U32    uint32  `struc:"little"` // 0f 00 00 00
34         U64    uint64  `struc:"little"` // 10 00 00 00 00 00 00 00
35         BoolT  bool    // 01
36         BoolF  bool    // 00
37         Byte4  [4]byte // "efgh"
38         Float1 float32 // 41 a0 00 00
39         Float2 float64 // 41 35 00 00 00 00 00 00
40
41         Size int    `struc:"sizeof=Str,little"` // 0a 00 00 00
42         Str  string `struc:"[]byte"`            // "ijklmnopqr"
43         Strb string `struc:"[4]byte"`           // "stuv"
44
45         Size2 int    `struc:"uint8,sizeof=Str2"` // 04
46         Str2  string // "1234"
47
48         Size3 int    `struc:"uint8,sizeof=Bstr"` // 04
49         Bstr  []byte // "5678"
50
51         Nested  Nested  // 00 00 00 01
52         NestedP *Nested // 00 00 00 02
53         TestP64 *int    `struc:"int64"` // 00 00 00 05
54
55         NestedSize int      `struc:"sizeof=NestedA"` // 00 00 00 02
56         NestedA    []Nested // [00 00 00 03, 00 00 00 04]
57
58         Skip int `struc:"skip"`
59
60         CustomTypeSize    Int3   `struc:"sizeof=CustomTypeSizeArr"` // 00 00 00 04
61         CustomTypeSizeArr []byte // "ABCD"
62 }
63
64 var five = 5
65
66 var reference = &Example{
67         nil,
68         1, 2, 3, 4, 5, 6, 7, 8, 0, []byte{'a', 'b', 'c', 'd'},
69         9, 10, 11, 12, 13, 14, 15, 16, true, false, [4]byte{'e', 'f', 'g', 'h'},
70         20, 21,
71         10, "ijklmnopqr", "stuv",
72         4, "1234",
73         4, []byte("5678"),
74         Nested{1}, &Nested{2}, &five,
75         6, []Nested{{3}, {4}, {5}, {6}, {7}, {8}},
76         0,
77         Int3(4), []byte("ABCD"),
78 }
79
80 var referenceBytes = []byte{
81         0, 0, 0, 0, 0, // pad(5)
82         1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, // fake int8-int64(1-4)
83         5, 6, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, // fake little-endian uint8-uint64(5-8)
84         0,                  // fake bool(0)
85         'a', 'b', 'c', 'd', // fake [4]byte
86
87         9, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, // real int8-int64(9-12)
88         13, 14, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, // real little-endian uint8-uint64(13-16)
89         1, 0, // real bool(1), bool(0)
90         'e', 'f', 'g', 'h', // real [4]byte
91         65, 160, 0, 0, // real float32(20)
92         64, 53, 0, 0, 0, 0, 0, 0, // real float64(21)
93
94         10, 0, 0, 0, // little-endian int32(10) sizeof=Str
95         'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', // Str
96         's', 't', 'u', 'v', // fake string([4]byte)
97         04, '1', '2', '3', '4', // real string
98         04, '5', '6', '7', '8', // fake []byte(string)
99
100         1, 2, // Nested{1}, Nested{2}
101         0, 0, 0, 0, 0, 0, 0, 5, // &five
102
103         0, 0, 0, 6, // int32(6)
104         3, 4, 5, 6, 7, 8, // [Nested{3}, ...Nested{8}]
105
106         0, 0, 4, 'A', 'B', 'C', 'D', // Int3(4), []byte("ABCD")
107 }
108
109 func TestCodec(t *testing.T) {
110         var buf bytes.Buffer
111         if err := Pack(&buf, reference); err != nil {
112                 t.Fatal(err)
113         }
114         out := &Example{}
115         if err := Unpack(&buf, out); err != nil {
116                 t.Fatal(err)
117         }
118         if !reflect.DeepEqual(reference, out) {
119                 t.Fatal("encode/decode failed")
120         }
121 }
122
123 func TestEncode(t *testing.T) {
124         var buf bytes.Buffer
125         if err := Pack(&buf, reference); err != nil {
126                 t.Fatal(err)
127         }
128         if !bytes.Equal(buf.Bytes(), referenceBytes) {
129                 t.Fatal("encode failed")
130         }
131 }
132
133 func TestDecode(t *testing.T) {
134         buf := bytes.NewReader(referenceBytes)
135         out := &Example{}
136         if err := Unpack(buf, out); err != nil {
137                 t.Fatal(err)
138         }
139         if !reflect.DeepEqual(reference, out) {
140                 t.Fatal("decode failed")
141         }
142 }
143
144 func TestSizeof(t *testing.T) {
145         size, err := Sizeof(reference)
146         if err != nil {
147                 t.Fatal(err)
148         }
149         if size != len(referenceBytes) {
150                 t.Fatal("sizeof failed")
151         }
152 }
153
154 type ExampleEndian struct {
155         T int `struc:"int16,big"`
156 }
157
158 func TestEndianSwap(t *testing.T) {
159         var buf bytes.Buffer
160         big := &ExampleEndian{1}
161         if err := PackWithOrder(&buf, big, binary.BigEndian); err != nil {
162                 t.Fatal(err)
163         }
164         little := &ExampleEndian{}
165         if err := UnpackWithOrder(&buf, little, binary.LittleEndian); err != nil {
166                 t.Fatal(err)
167         }
168         if little.T != 256 {
169                 t.Fatal("big -> little conversion failed")
170         }
171 }
172
173 func TestNilValue(t *testing.T) {
174         var buf bytes.Buffer
175         if err := Pack(&buf, nil); err == nil {
176                 t.Fatal("failed throw error for bad struct value")
177         }
178         if err := Unpack(&buf, nil); err == nil {
179                 t.Fatal("failed throw error for bad struct value")
180         }
181         if _, err := Sizeof(nil); err == nil {
182                 t.Fatal("failed to throw error for bad struct value")
183         }
184 }
185
186 type sliceUnderrun struct {
187         Str string   `struc:"[10]byte"`
188         Arr []uint16 `struc:"[10]uint16"`
189 }
190
191 func TestSliceUnderrun(t *testing.T) {
192         var buf bytes.Buffer
193         v := sliceUnderrun{
194                 Str: "foo",
195                 Arr: []uint16{1, 2, 3},
196         }
197         if err := Pack(&buf, &v); err != nil {
198                 t.Fatal(err)
199         }
200 }