1package cbor 2 3import ( 4 "encoding/hex" 5 "net" 6 "testing" 7) 8 9var enc = Encoder{} 10 11func TestAppendNil(t *testing.T) { 12 s := enc.AppendNil([]byte{}) 13 got := string(s) 14 want := "\xf6" 15 if got != want { 16 t.Errorf("appendNull() = 0x%s, want: 0x%s", hex.EncodeToString(s), 17 hex.EncodeToString([]byte(want))) 18 } 19} 20 21var booleanTestCases = []struct { 22 val bool 23 binary string 24 json string 25}{ 26 {true, "\xf5", "true"}, 27 {false, "\xf4", "false"}, 28} 29 30func TestAppendBool(t *testing.T) { 31 for _, tc := range booleanTestCases { 32 s := enc.AppendBool([]byte{}, tc.val) 33 got := string(s) 34 if got != tc.binary { 35 t.Errorf("AppendBool(%s)=0x%s, want: 0x%s", 36 tc.json, hex.EncodeToString(s), 37 hex.EncodeToString([]byte(tc.binary))) 38 } 39 } 40} 41 42var booleanArrayTestCases = []struct { 43 val []bool 44 binary string 45 json string 46}{ 47 {[]bool{true, false, true}, "\x83\xf5\xf4\xf5", "[true,false,true]"}, 48 {[]bool{true, false, false, true, false, true}, "\x86\xf5\xf4\xf4\xf5\xf4\xf5", "[true,false,false,true,false,true]"}, 49} 50 51func TestAppendBoolArray(t *testing.T) { 52 for _, tc := range booleanArrayTestCases { 53 s := enc.AppendBools([]byte{}, tc.val) 54 got := string(s) 55 if got != tc.binary { 56 t.Errorf("AppendBools(%s)=0x%s, want: 0x%s", 57 tc.json, hex.EncodeToString(s), 58 hex.EncodeToString([]byte(tc.binary))) 59 } 60 } 61} 62 63var integerTestCases = []struct { 64 val int 65 binary string 66}{ 67 // Value included in the type. 68 {0, "\x00"}, 69 {1, "\x01"}, 70 {2, "\x02"}, 71 {3, "\x03"}, 72 {8, "\x08"}, 73 {9, "\x09"}, 74 {10, "\x0a"}, 75 {22, "\x16"}, 76 {23, "\x17"}, 77 // Value in 1 byte. 78 {24, "\x18\x18"}, 79 {25, "\x18\x19"}, 80 {26, "\x18\x1a"}, 81 {100, "\x18\x64"}, 82 {254, "\x18\xfe"}, 83 {255, "\x18\xff"}, 84 // Value in 2 bytes. 85 {256, "\x19\x01\x00"}, 86 {257, "\x19\x01\x01"}, 87 {1000, "\x19\x03\xe8"}, 88 {0xFFFF, "\x19\xff\xff"}, 89 // Value in 4 bytes. 90 {0x10000, "\x1a\x00\x01\x00\x00"}, 91 {0x7FFFFFFE, "\x1a\x7f\xff\xff\xfe"}, 92 {1000000, "\x1a\x00\x0f\x42\x40"}, 93 // Negative number test cases. 94 // Value included in the type. 95 {-1, "\x20"}, 96 {-2, "\x21"}, 97 {-3, "\x22"}, 98 {-10, "\x29"}, 99 {-21, "\x34"}, 100 {-22, "\x35"}, 101 {-23, "\x36"}, 102 {-24, "\x37"}, 103 // Value in 1 byte. 104 {-25, "\x38\x18"}, 105 {-26, "\x38\x19"}, 106 {-100, "\x38\x63"}, 107 {-254, "\x38\xfd"}, 108 {-255, "\x38\xfe"}, 109 {-256, "\x38\xff"}, 110 // Value in 2 bytes. 111 {-257, "\x39\x01\x00"}, 112 {-258, "\x39\x01\x01"}, 113 {-1000, "\x39\x03\xe7"}, 114 // Value in 4 bytes. 115 {-0x10001, "\x3a\x00\x01\x00\x00"}, 116 {-0x7FFFFFFE, "\x3a\x7f\xff\xff\xfd"}, 117 {-1000000, "\x3a\x00\x0f\x42\x3f"}, 118 119} 120 121func TestAppendInt(t *testing.T) { 122 for _, tc := range integerTestCases { 123 s := enc.AppendInt([]byte{}, tc.val) 124 got := string(s) 125 if got != tc.binary { 126 t.Errorf("AppendInt(0x%x)=0x%s, want: 0x%s", 127 tc.val, hex.EncodeToString(s), 128 hex.EncodeToString([]byte(tc.binary))) 129 } 130 } 131} 132 133var integerArrayTestCases = []struct { 134 val []int 135 binary string 136 json string 137}{ 138 {[]int{-1, 0, 200, 20}, "\x84\x20\x00\x18\xc8\x14", "[-1,0,200,20]"}, 139 {[]int{-200, -10, 200, 400}, "\x84\x38\xc7\x29\x18\xc8\x19\x01\x90", "[-200,-10,200,400]"}, 140 {[]int{1, 2, 3}, "\x83\x01\x02\x03", "[1,2,3]"}, 141 {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, 142 "\x98\x19\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x18\x18\x19", 143 "[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]"}, 144} 145 146func TestAppendIntArray(t *testing.T) { 147 for _, tc := range integerArrayTestCases { 148 s := enc.AppendInts([]byte{}, tc.val) 149 got := string(s) 150 if got != tc.binary { 151 t.Errorf("AppendInts(%s)=0x%s, want: 0x%s", 152 tc.json, hex.EncodeToString(s), 153 hex.EncodeToString([]byte(tc.binary))) 154 } 155 } 156} 157 158var float32TestCases = []struct { 159 val float32 160 binary string 161}{ 162 {0.0, "\xfa\x00\x00\x00\x00"}, 163 {-0.0, "\xfa\x00\x00\x00\x00"}, 164 {1.0, "\xfa\x3f\x80\x00\x00"}, 165 {1.5, "\xfa\x3f\xc0\x00\x00"}, 166 {65504.0, "\xfa\x47\x7f\xe0\x00"}, 167 {-4.0, "\xfa\xc0\x80\x00\x00"}, 168 {0.00006103515625, "\xfa\x38\x80\x00\x00"}, 169} 170 171func TestAppendFloat32(t *testing.T) { 172 for _, tc := range float32TestCases { 173 s := enc.AppendFloat32([]byte{}, tc.val) 174 got := string(s) 175 if got != tc.binary { 176 t.Errorf("AppendFloat32(%f)=0x%s, want: 0x%s", 177 tc.val, hex.EncodeToString(s), 178 hex.EncodeToString([]byte(tc.binary))) 179 } 180 } 181} 182 183var ipAddrTestCases = []struct { 184 ipaddr net.IP 185 text string // ASCII representation of ipaddr 186 binary string // CBOR representation of ipaddr 187}{ 188 {net.IP{10, 0, 0, 1}, "\"10.0.0.1\"", "\xd9\x01\x04\x44\x0a\x00\x00\x01"}, 189 {net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34}, 190 "\"2001:db8:85a3::8a2e:370:7334\"", 191 "\xd9\x01\x04\x50\x20\x01\x0d\xb8\x85\xa3\x00\x00\x00\x00\x8a\x2e\x03\x70\x73\x34"}, 192} 193 194func TestAppendNetworkAddr(t *testing.T) { 195 for _, tc := range ipAddrTestCases { 196 s := enc.AppendIPAddr([]byte{}, tc.ipaddr) 197 got := string(s) 198 if got != tc.binary { 199 t.Errorf("AppendIPAddr(%s)=0x%s, want: 0x%s", 200 tc.ipaddr, hex.EncodeToString(s), 201 hex.EncodeToString([]byte(tc.binary))) 202 } 203 } 204} 205 206var macAddrTestCases = []struct { 207 macaddr net.HardwareAddr 208 text string // ASCII representation of macaddr 209 binary string // CBOR representation of macaddr 210}{ 211 {net.HardwareAddr{0x12, 0x34, 0x56, 0x78, 0x90, 0xab}, "\"12:34:56:78:90:ab\"", "\xd9\x01\x04\x46\x12\x34\x56\x78\x90\xab"}, 212 {net.HardwareAddr{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3}, "\"20:01:0d:b8:85:a3\"", "\xd9\x01\x04\x46\x20\x01\x0d\xb8\x85\xa3"}, 213} 214 215func TestAppendMacAddr(t *testing.T) { 216 for _, tc := range macAddrTestCases { 217 s := enc.AppendMACAddr([]byte{}, tc.macaddr) 218 got := string(s) 219 if got != tc.binary { 220 t.Errorf("AppendMACAddr(%s)=0x%s, want: 0x%s", 221 tc.macaddr.String(), hex.EncodeToString(s), 222 hex.EncodeToString([]byte(tc.binary))) 223 } 224 } 225} 226 227var IPPrefixTestCases = []struct { 228 pfx net.IPNet 229 text string // ASCII representation of pfx 230 binary string // CBOR representation of pfx 231}{ 232 {net.IPNet{IP: net.IP{0, 0, 0, 0}, Mask: net.CIDRMask(0, 32)}, "\"0.0.0.0/0\"", "\xd9\x01\x05\xa1\x44\x00\x00\x00\x00\x00"}, 233 {net.IPNet{IP: net.IP{192, 168, 0, 100}, Mask: net.CIDRMask(24, 32)}, "\"192.168.0.100/24\"", 234 "\xd9\x01\x05\xa1\x44\xc0\xa8\x00\x64\x18\x18"}, 235} 236 237func TestAppendIPPrefix(t *testing.T) { 238 for _, tc := range IPPrefixTestCases { 239 s := enc.AppendIPPrefix([]byte{}, tc.pfx) 240 got := string(s) 241 if got != tc.binary { 242 t.Errorf("AppendIPPrefix(%s)=0x%s, want: 0x%s", 243 tc.pfx.String(), hex.EncodeToString(s), 244 hex.EncodeToString([]byte(tc.binary))) 245 } 246 } 247} 248 249func BenchmarkAppendInt(b *testing.B) { 250 type st struct { 251 sz byte 252 val int64 253 } 254 tests := map[string]st{ 255 "int-Positive": {sz: 0, val: 10000}, 256 "int-Negative": {sz: 0, val: -10000}, 257 "uint8": {sz: 1, val: 100}, 258 "uint16": {sz: 2, val: 0xfff}, 259 "uint32": {sz: 4, val: 0xffffff}, 260 "uint64": {sz: 8, val: 0xffffffffff}, 261 "int8": {sz: 21, val: -120}, 262 "int16": {sz: 22, val: -1200}, 263 "int32": {sz: 23, val: 32000}, 264 "int64": {sz: 24, val: 0xffffffffff}, 265 } 266 for name, str := range tests { 267 b.Run(name, func(b *testing.B) { 268 buf := make([]byte, 0, 100) 269 for i := 0; i < b.N; i++ { 270 switch str.sz { 271 case 0: 272 _ = enc.AppendInt(buf, int(str.val)) 273 case 1: 274 _ = enc.AppendUint8(buf, uint8(str.val)) 275 case 2: 276 _ = enc.AppendUint16(buf, uint16(str.val)) 277 case 4: 278 _ = enc.AppendUint32(buf, uint32(str.val)) 279 case 8: 280 _ = enc.AppendUint64(buf, uint64(str.val)) 281 case 21: 282 _ = enc.AppendInt8(buf, int8(str.val)) 283 case 22: 284 _ = enc.AppendInt16(buf, int16(str.val)) 285 case 23: 286 _ = enc.AppendInt32(buf, int32(str.val)) 287 case 24: 288 _ = enc.AppendInt64(buf, int64(str.val)) 289 } 290 } 291 }) 292 } 293} 294 295func BenchmarkAppendFloat(b *testing.B) { 296 type st struct { 297 sz byte 298 val float64 299 } 300 tests := map[string]st{ 301 "Float32": {sz: 4, val: 10000.12345}, 302 "Float64": {sz: 8, val: -10000.54321}, 303 } 304 for name, str := range tests { 305 b.Run(name, func(b *testing.B) { 306 buf := make([]byte, 0, 100) 307 for i := 0; i < b.N; i++ { 308 switch str.sz { 309 case 4: 310 _ = enc.AppendFloat32(buf, float32(str.val)) 311 case 8: 312 _ = enc.AppendFloat64(buf, str.val) 313 } 314 } 315 }) 316 } 317} 318