initial commit
[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         CustomTypeSize    Int3   `struc:"sizeof=CustomTypeSizeArr"` // 00 00 00 04
59         CustomTypeSizeArr []byte // "ABCD"
60 }
61
62 var five = 5
63
64 var reference = &Example{
65         nil,
66         1, 2, 3, 4, 5, 6, 7, 8, 0, []byte{'a', 'b', 'c', 'd'},
67         9, 10, 11, 12, 13, 14, 15, 16, true, false, [4]byte{'e', 'f', 'g', 'h'},
68         20, 21,
69         10, "ijklmnopqr", "stuv",
70         4, "1234",
71         4, []byte("5678"),
72         Nested{1}, &Nested{2}, &five,
73         6, []Nested{{3}, {4}, {5}, {6}, {7}, {8}},
74         Int3(4), []byte("ABCD"),
75 }
76
77 var referenceBytes = []byte{
78         0, 0, 0, 0, 0, // pad(5)
79         1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, // fake int8-int64(1-4)
80         5, 6, 0, 7, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, // fake little-endian uint8-uint64(5-8)
81         0,                  // fake bool(0)
82         'a', 'b', 'c', 'd', // fake [4]byte
83
84         9, 0, 10, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 12, // real int8-int64(9-12)
85         13, 14, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, // real little-endian uint8-uint64(13-16)
86         1, 0, // real bool(1), bool(0)
87         'e', 'f', 'g', 'h', // real [4]byte
88         65, 160, 0, 0, // real float32(20)
89         64, 53, 0, 0, 0, 0, 0, 0, // real float64(21)
90
91         10, 0, 0, 0, // little-endian int32(10) sizeof=Str
92         'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', // Str
93         's', 't', 'u', 'v', // fake string([4]byte)
94         04, '1', '2', '3', '4', // real string
95         04, '5', '6', '7', '8', // fake []byte(string)
96
97         1, 2, // Nested{1}, Nested{2}
98         0, 0, 0, 0, 0, 0, 0, 5, // &five
99
100         0, 0, 0, 6, // int32(6)
101         3, 4, 5, 6, 7, 8, // [Nested{3}, ...Nested{8}]
102
103         0, 0, 4, 'A', 'B', 'C', 'D', // Int3(4), []byte("ABCD")
104 }
105
106 func TestCodec(t *testing.T) {
107         var buf bytes.Buffer
108         if err := Pack(&buf, reference); err != nil {
109                 t.Fatal(err)
110         }
111         out := &Example{}
112         if err := Unpack(&buf, out); err != nil {
113                 t.Fatal(err)
114         }
115         if !reflect.DeepEqual(reference, out) {
116                 t.Fatal("encode/decode failed")
117         }
118 }
119
120 func TestEncode(t *testing.T) {
121         var buf bytes.Buffer
122         if err := Pack(&buf, reference); err != nil {
123                 t.Fatal(err)
124         }
125         if !bytes.Equal(buf.Bytes(), referenceBytes) {
126                 t.Fatal("encode failed")
127         }
128 }
129
130 func TestDecode(t *testing.T) {
131         buf := bytes.NewReader(referenceBytes)
132         out := &Example{}
133         if err := Unpack(buf, out); err != nil {
134                 t.Fatal(err)
135         }
136         if !reflect.DeepEqual(reference, out) {
137                 t.Fatal("decode failed")
138         }
139 }
140
141 func TestSizeof(t *testing.T) {
142         size, err := Sizeof(reference)
143         if err != nil {
144                 t.Fatal(err)
145         }
146         if size != len(referenceBytes) {
147                 t.Fatal("sizeof failed")
148         }
149 }
150
151 type ExampleEndian struct {
152         T int `struc:"int16,big"`
153 }
154
155 func TestEndianSwap(t *testing.T) {
156         var buf bytes.Buffer
157         big := &ExampleEndian{1}
158         if err := PackWithOrder(&buf, big, binary.BigEndian); err != nil {
159                 t.Fatal(err)
160         }
161         little := &ExampleEndian{}
162         if err := UnpackWithOrder(&buf, little, binary.LittleEndian); err != nil {
163                 t.Fatal(err)
164         }
165         if little.T != 256 {
166                 t.Fatal("big -> little conversion failed")
167         }
168 }
169
170 func TestNilValue(t *testing.T) {
171         var buf bytes.Buffer
172         if err := Pack(&buf, nil); err == nil {
173                 t.Fatal("failed throw error for bad struct value")
174         }
175         if err := Unpack(&buf, nil); err == nil {
176                 t.Fatal("failed throw error for bad struct value")
177         }
178         if _, err := Sizeof(nil); err == nil {
179                 t.Fatal("failed to throw error for bad struct value")
180         }
181 }
182
183 type sliceUnderrun struct {
184         Str string   `struc:"[10]byte"`
185         Arr []uint16 `struc:"[10]uint16"`
186 }
187
188 func TestSliceUnderrun(t *testing.T) {
189         var buf bytes.Buffer
190         v := sliceUnderrun{
191                 Str: "foo",
192                 Arr: []uint16{1, 2, 3},
193         }
194         if err := Pack(&buf, &v); err != nil {
195                 t.Fatal(err)
196         }
197 }