cbor_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license found in the LICENSE file.
  3. package codec
  4. import (
  5. "bytes"
  6. "encoding/hex"
  7. "encoding/json"
  8. "os"
  9. "strconv"
  10. "testing"
  11. )
  12. func TestCborIndefiniteLength(t *testing.T) {
  13. oldMapType := testCborH.MapType
  14. defer func() {
  15. testCborH.MapType = oldMapType
  16. }()
  17. testCborH.MapType = testMapStrIntfTyp
  18. // var (
  19. // M1 map[string][]byte
  20. // M2 map[uint64]bool
  21. // L1 []interface{}
  22. // S1 []string
  23. // B1 []byte
  24. // )
  25. var v, vv interface{}
  26. // define it (v), encode it using indefinite lengths, decode it (vv), compare v to vv
  27. v = map[string]interface{}{
  28. "one-byte-key": []byte{1, 2, 3, 4, 5, 6},
  29. "two-string-key": "two-value",
  30. "three-list-key": []interface{}{true, false, uint64(1), int64(-1)},
  31. }
  32. var buf bytes.Buffer
  33. // buf.Reset()
  34. e := NewEncoder(&buf, testCborH)
  35. buf.WriteByte(cborBdIndefiniteMap)
  36. //----
  37. buf.WriteByte(cborBdIndefiniteString)
  38. e.MustEncode("one-")
  39. e.MustEncode("byte-")
  40. e.MustEncode("key")
  41. buf.WriteByte(cborBdBreak)
  42. buf.WriteByte(cborBdIndefiniteBytes)
  43. e.MustEncode([]byte{1, 2, 3})
  44. e.MustEncode([]byte{4, 5, 6})
  45. buf.WriteByte(cborBdBreak)
  46. //----
  47. buf.WriteByte(cborBdIndefiniteString)
  48. e.MustEncode("two-")
  49. e.MustEncode("string-")
  50. e.MustEncode("key")
  51. buf.WriteByte(cborBdBreak)
  52. buf.WriteByte(cborBdIndefiniteString)
  53. e.MustEncode([]byte("two-")) // encode as bytes, to check robustness of code
  54. e.MustEncode([]byte("value"))
  55. buf.WriteByte(cborBdBreak)
  56. //----
  57. buf.WriteByte(cborBdIndefiniteString)
  58. e.MustEncode("three-")
  59. e.MustEncode("list-")
  60. e.MustEncode("key")
  61. buf.WriteByte(cborBdBreak)
  62. buf.WriteByte(cborBdIndefiniteArray)
  63. e.MustEncode(true)
  64. e.MustEncode(false)
  65. e.MustEncode(uint64(1))
  66. e.MustEncode(int64(-1))
  67. buf.WriteByte(cborBdBreak)
  68. buf.WriteByte(cborBdBreak) // close map
  69. NewDecoderBytes(buf.Bytes(), testCborH).MustDecode(&vv)
  70. if err := deepEqual(v, vv); err != nil {
  71. logT(t, "-------- Before and After marshal do not match: Error: %v", err)
  72. logT(t, " ....... GOLDEN: (%T) %#v", v, v)
  73. logT(t, " ....... DECODED: (%T) %#v", vv, vv)
  74. failT(t)
  75. }
  76. }
  77. type testCborGolden struct {
  78. Base64 string `json:"cbor"`
  79. Hex string `json:"hex"`
  80. Roundtrip bool `json:"roundtrip"`
  81. Decoded interface{} `json:"decoded"`
  82. }
  83. // __TestCborGoldens is disabled because it includes numbers outside the range of int64/uint64
  84. // and it doesn't support diagnostic checking.
  85. func __TestCborGoldens(t *testing.T) {
  86. // decode test-cbor-goldens.json into a list of []*testCborGolden
  87. // for each one,
  88. // - decode hex into []byte bs
  89. // - decode bs into interface{} v
  90. // - compare both using deepequal
  91. // - for any miss, record it
  92. var gs []*testCborGolden
  93. f, err := os.Open("test-cbor-goldens.json")
  94. if err != nil {
  95. logT(t, "error opening test-cbor-goldens.json: %v", err)
  96. failT(t)
  97. }
  98. d := json.NewDecoder(f)
  99. d.UseNumber()
  100. err = d.Decode(&gs)
  101. if err != nil {
  102. logT(t, "error json decoding test-cbor-goldens.json: %v", err)
  103. failT(t)
  104. }
  105. for i, g := range gs {
  106. bs, err := hex.DecodeString(g.Hex)
  107. if err != nil {
  108. logT(t, "[%v] error hex decoding %s [%v]: %v", i, g.Hex, err)
  109. failT(t)
  110. }
  111. var v interface{}
  112. NewDecoderBytes(bs, testCborH).MustDecode(&v)
  113. if _, ok := v.(RawExt); ok {
  114. continue
  115. }
  116. if x, ok := g.Decoded.(json.Number); ok {
  117. var doContinue bool
  118. js := x.String()
  119. switch v2 := v.(type) {
  120. case float64:
  121. xx, err := strconv.ParseFloat(js, 64)
  122. if err != nil {
  123. logT(t, "[%v] cannot parse decoded value as float64 (expect %v): %v", i, v2, err)
  124. failT(t)
  125. }
  126. if xx != v2 {
  127. logT(t, "[%v] float64 value mismatch: golden: %v, decoded: %v", i, xx, v2)
  128. failT(t)
  129. }
  130. doContinue = true
  131. case int64:
  132. xx, err := strconv.ParseInt(js, 10, 64)
  133. if err != nil {
  134. logT(t, "[%v] cannot parse decoded value as int64 (expect %v): %v", i, v2, err)
  135. failT(t)
  136. }
  137. if xx != v2 {
  138. logT(t, "[%v] int64 value mismatch: golden: %v, decoded: %v", i, xx, v2)
  139. failT(t)
  140. }
  141. doContinue = true
  142. case uint64:
  143. xx, err := strconv.ParseUint(js, 10, 64)
  144. if err != nil {
  145. logT(t, "[%v] cannot parse decoded value as uint64 (expect %v): %v", i, v2, err)
  146. failT(t)
  147. }
  148. if xx != v2 {
  149. logT(t, "[%v] uint64 value mismatch: golden: %v, decoded: %v", i, xx, v2)
  150. failT(t)
  151. }
  152. doContinue = true
  153. }
  154. if doContinue {
  155. continue
  156. }
  157. }
  158. if err = deepEqual(g.Decoded, v); err != nil {
  159. logT(t, "[%v] deepEqual error: %v", i, err)
  160. logT(t, " ....... GOLDEN: (%T) %#v", g.Decoded, g.Decoded)
  161. logT(t, " ....... DECODED: (%T) %#v", v, v)
  162. failT(t)
  163. }
  164. }
  165. }