1package cbor 2 3import ( 4 "bytes" 5 "encoding/hex" 6 "testing" 7 "time" 8) 9 10func TestDecodeInteger(t *testing.T) { 11 for _, tc := range integerTestCases { 12 gotv := decodeInteger(getReader(tc.binary)) 13 if gotv != int64(tc.val) { 14 t.Errorf("decodeInteger(0x%s)=0x%d, want: 0x%d", 15 hex.EncodeToString([]byte(tc.binary)), gotv, tc.val) 16 } 17 } 18} 19 20func TestDecodeString(t *testing.T) { 21 for _, tt := range encodeStringTests { 22 got := decodeUTF8String(getReader(tt.binary)) 23 if string(got) != "\""+tt.json+"\"" { 24 t.Errorf("DecodeString(0x%s)=%s, want:\"%s\"\n", hex.EncodeToString([]byte(tt.binary)), string(got), 25 hex.EncodeToString([]byte(tt.json))) 26 } 27 } 28} 29 30func TestDecodeArray(t *testing.T) { 31 for _, tc := range integerArrayTestCases { 32 buf := bytes.NewBuffer([]byte{}) 33 array2Json(getReader(tc.binary), buf) 34 if buf.String() != tc.json { 35 t.Errorf("array2Json(0x%s)=%s, want: %s", hex.EncodeToString([]byte(tc.binary)), buf.String(), tc.json) 36 } 37 } 38 //Unspecified Length Array 39 var infiniteArrayTestCases = []struct { 40 in string 41 out string 42 }{ 43 {"\x9f\x20\x00\x18\xc8\x14\xff", "[-1,0,200,20]"}, 44 {"\x9f\x38\xc7\x29\x18\xc8\x19\x01\x90\xff", "[-200,-10,200,400]"}, 45 {"\x9f\x01\x02\x03\xff", "[1,2,3]"}, 46 {"\x9f\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\xff", 47 "[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]"}, 48 } 49 for _, tc := range infiniteArrayTestCases { 50 buf := bytes.NewBuffer([]byte{}) 51 array2Json(getReader(tc.in), buf) 52 if buf.String() != tc.out { 53 t.Errorf("array2Json(0x%s)=%s, want: %s", hex.EncodeToString([]byte(tc.out)), buf.String(), tc.out) 54 } 55 } 56 for _, tc := range booleanArrayTestCases { 57 buf := bytes.NewBuffer([]byte{}) 58 array2Json(getReader(tc.binary), buf) 59 if buf.String() != tc.json { 60 t.Errorf("array2Json(0x%s)=%s, want: %s", hex.EncodeToString([]byte(tc.binary)), buf.String(), tc.json) 61 } 62 } 63 //TODO add cases for arrays of other types 64} 65 66var infiniteMapDecodeTestCases = []struct { 67 bin []byte 68 json string 69}{ 70 {[]byte("\xbf\x64IETF\x20\xff"), "{\"IETF\":-1}"}, 71 {[]byte("\xbf\x65Array\x84\x20\x00\x18\xc8\x14\xff"), "{\"Array\":[-1,0,200,20]}"}, 72} 73 74var mapDecodeTestCases = []struct { 75 bin []byte 76 json string 77}{ 78 {[]byte("\xa2\x64IETF\x20"), "{\"IETF\":-1}"}, 79 {[]byte("\xa2\x65Array\x84\x20\x00\x18\xc8\x14"), "{\"Array\":[-1,0,200,20]}"}, 80} 81 82func TestDecodeMap(t *testing.T) { 83 for _, tc := range mapDecodeTestCases { 84 buf := bytes.NewBuffer([]byte{}) 85 map2Json(getReader(string(tc.bin)), buf) 86 if buf.String() != tc.json { 87 t.Errorf("map2Json(0x%s)=%s, want: %s", hex.EncodeToString(tc.bin), buf.String(), tc.json) 88 } 89 } 90 for _, tc := range infiniteMapDecodeTestCases { 91 buf := bytes.NewBuffer([]byte{}) 92 map2Json(getReader(string(tc.bin)), buf) 93 if buf.String() != tc.json { 94 t.Errorf("map2Json(0x%s)=%s, want: %s", hex.EncodeToString(tc.bin), buf.String(), tc.json) 95 } 96 } 97} 98 99func TestDecodeBool(t *testing.T) { 100 for _, tc := range booleanTestCases { 101 got := decodeSimpleFloat(getReader(tc.binary)) 102 if string(got) != tc.json { 103 t.Errorf("decodeSimpleFloat(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.binary)), string(got), tc.json) 104 } 105 } 106} 107 108func TestDecodeFloat(t *testing.T) { 109 for _, tc := range float32TestCases { 110 got, _ := decodeFloat(getReader(tc.binary)) 111 if got != float64(tc.val) { 112 t.Errorf("decodeFloat(0x%s)=%f, want:%f", hex.EncodeToString([]byte(tc.binary)), got, tc.val) 113 } 114 } 115} 116 117func TestDecodeTimestamp(t *testing.T) { 118 decodeTimeZone, _ = time.LoadLocation("UTC") 119 for _, tc := range timeIntegerTestcases { 120 tm := decodeTagData(getReader(tc.binary)) 121 if string(tm) != "\""+tc.rfcStr+"\"" { 122 t.Errorf("decodeFloat(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.binary)), tm, tc.rfcStr) 123 } 124 } 125 for _, tc := range timeFloatTestcases { 126 tm := decodeTagData(getReader(tc.out)) 127 //Since we convert to float and back - it may be slightly off - so 128 //we cannot check for exact equality instead, we'll check it is 129 //very close to each other Less than a Microsecond (lets not yet do nanosec) 130 131 got, _ := time.Parse(string(tm), string(tm)) 132 want, _ := time.Parse(tc.rfcStr, tc.rfcStr) 133 if got.Sub(want) > time.Microsecond { 134 t.Errorf("decodeFloat(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.out)), tm, tc.rfcStr) 135 } 136 } 137} 138 139func TestDecodeNetworkAddr(t *testing.T) { 140 for _, tc := range ipAddrTestCases { 141 d1 := decodeTagData(getReader(tc.binary)) 142 if string(d1) != tc.text { 143 t.Errorf("decodeNetworkAddr(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.binary)), d1, tc.text) 144 } 145 } 146} 147 148func TestDecodeMACAddr(t *testing.T) { 149 for _, tc := range macAddrTestCases { 150 d1 := decodeTagData(getReader(tc.binary)) 151 if string(d1) != tc.text { 152 t.Errorf("decodeNetworkAddr(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.binary)), d1, tc.text) 153 } 154 } 155} 156 157func TestDecodeIPPrefix(t *testing.T) { 158 for _, tc := range IPPrefixTestCases { 159 d1 := decodeTagData(getReader(tc.binary)) 160 if string(d1) != tc.text { 161 t.Errorf("decodeIPPrefix(0x%s)=%s, want:%s", hex.EncodeToString([]byte(tc.binary)), d1, tc.text) 162 } 163 } 164} 165 166var compositeCborTestCases = []struct { 167 binary []byte 168 json string 169}{ 170 {[]byte("\xbf\x64IETF\x20\x65Array\x9f\x20\x00\x18\xc8\x14\xff\xff"), "{\"IETF\":-1,\"Array\":[-1,0,200,20]}\n"}, 171 {[]byte("\xbf\x64IETF\x64YES!\x65Array\x9f\x20\x00\x18\xc8\x14\xff\xff"), "{\"IETF\":\"YES!\",\"Array\":[-1,0,200,20]}\n"}, 172} 173 174func TestDecodeCbor2Json(t *testing.T) { 175 for _, tc := range compositeCborTestCases { 176 buf := bytes.NewBuffer([]byte{}) 177 err := Cbor2JsonManyObjects(getReader(string(tc.binary)), buf) 178 if buf.String() != tc.json || err != nil { 179 t.Errorf("cbor2JsonManyObjects(0x%s)=%s, want: %s, err:%s", hex.EncodeToString(tc.binary), buf.String(), tc.json, err.Error()) 180 } 181 } 182} 183 184var negativeCborTestCases = []struct { 185 binary []byte 186 errStr string 187}{ 188 {[]byte("\xb9\x64IETF\x20\x65Array\x9f\x20\x00\x18\xc8\x14"), "Tried to Read 18 Bytes.. But hit end of file"}, 189 {[]byte("\xbf\x64IETF\x20\x65Array\x9f\x20\x00\x18\xc8\x14"), "EOF"}, 190 {[]byte("\xbf\x14IETF\x20\x65Array\x9f\x20\x00\x18\xc8\x14"), "Tried to Read 40736 Bytes.. But hit end of file"}, 191 {[]byte("\xbf\x64IETF"), "EOF"}, 192 {[]byte("\xbf\x64IETF\x20\x65Array\x9f\x20\x00\x18\xc8\xff\xff\xff"), "Invalid Additional Type: 31 in decodeSimpleFloat"}, 193 {[]byte("\xbf\x64IETF\x20\x65Array"), "EOF"}, 194 {[]byte("\xbf\x64"), "Tried to Read 4 Bytes.. But hit end of file"}, 195} 196 197func TestDecodeNegativeCbor2Json(t *testing.T) { 198 for _, tc := range negativeCborTestCases { 199 buf := bytes.NewBuffer([]byte{}) 200 err := Cbor2JsonManyObjects(getReader(string(tc.binary)), buf) 201 if err == nil || err.Error() != tc.errStr { 202 t.Errorf("Expected error got:%s, want:%s", err, tc.errStr) 203 } 204 } 205} 206