type_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package test
  2. import (
  3. "testing"
  4. "reflect"
  5. "fmt"
  6. "github.com/google/gofuzz"
  7. "strings"
  8. "github.com/json-iterator/go"
  9. "encoding/json"
  10. "bytes"
  11. "github.com/davecgh/go-spew/spew"
  12. )
  13. var testCases []interface{}
  14. var asymmetricTestCases [][2]interface{}
  15. func Test_symmetric(t *testing.T) {
  16. for _, testCase := range testCases {
  17. valType := reflect.TypeOf(testCase).Elem()
  18. fz := fuzz.New().MaxDepth(10).NilChance(0.3)
  19. for i := 0; i < 100; i++ {
  20. beforePtrVal := reflect.New(valType)
  21. beforePtr := beforePtrVal.Interface()
  22. fz.Fuzz(beforePtr)
  23. before := beforePtrVal.Elem().Interface()
  24. jbStd, err := json.Marshal(before)
  25. if err != nil {
  26. t.Fatalf("failed to marshal with stdlib: %v", err)
  27. }
  28. if len(strings.TrimSpace(string(jbStd))) == 0 {
  29. t.Fatal("stdlib marshal produced empty result and no error")
  30. }
  31. jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
  32. if err != nil {
  33. t.Fatalf("failed to marshal with jsoniter: %v", err)
  34. }
  35. if len(strings.TrimSpace(string(jbIter))) == 0 {
  36. t.Fatal("jsoniter marshal produced empty result and no error")
  37. }
  38. if string(jbStd) != string(jbIter) {
  39. t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
  40. indent(jbStd, " "), indent(jbIter, " "), dump(before))
  41. }
  42. afterStdPtrVal := reflect.New(valType)
  43. afterStdPtr := afterStdPtrVal.Interface()
  44. err = json.Unmarshal(jbIter, afterStdPtr)
  45. if err != nil {
  46. t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
  47. err, indent(jbIter, " "))
  48. }
  49. afterIterPtrVal := reflect.New(valType)
  50. afterIterPtr := afterIterPtrVal.Interface()
  51. err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
  52. if err != nil {
  53. t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
  54. err, indent(jbIter, " "))
  55. }
  56. afterStd := afterStdPtrVal.Elem().Interface()
  57. afterIter := afterIterPtrVal.Elem().Interface()
  58. if fingerprint(afterStd) != fingerprint(afterIter) {
  59. t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
  60. dump(afterStd), dump(afterIter), indent(jbIter, " "))
  61. }
  62. }
  63. }
  64. }
  65. func Test_asymmetric(t *testing.T) {
  66. for _, testCase := range asymmetricTestCases {
  67. fromType := reflect.TypeOf(testCase[0]).Elem()
  68. toType := reflect.TypeOf(testCase[1]).Elem()
  69. fz := fuzz.New().MaxDepth(10).NilChance(0.3)
  70. for i := 0; i < 100; i++ {
  71. beforePtrVal := reflect.New(fromType)
  72. beforePtr := beforePtrVal.Interface()
  73. fz.Fuzz(beforePtr)
  74. before := beforePtrVal.Elem().Interface()
  75. jbStd, err := json.Marshal(before)
  76. if err != nil {
  77. t.Fatalf("failed to marshal with stdlib: %v", err)
  78. }
  79. if len(strings.TrimSpace(string(jbStd))) == 0 {
  80. t.Fatal("stdlib marshal produced empty result and no error")
  81. }
  82. jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
  83. if err != nil {
  84. t.Fatalf("failed to marshal with jsoniter: %v", err)
  85. }
  86. if len(strings.TrimSpace(string(jbIter))) == 0 {
  87. t.Fatal("jsoniter marshal produced empty result and no error")
  88. }
  89. if string(jbStd) != string(jbIter) {
  90. t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
  91. indent(jbStd, " "), indent(jbIter, " "), dump(before))
  92. }
  93. afterStdPtrVal := reflect.New(toType)
  94. afterStdPtr := afterStdPtrVal.Interface()
  95. err = json.Unmarshal(jbIter, afterStdPtr)
  96. if err != nil {
  97. t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
  98. err, indent(jbIter, " "))
  99. }
  100. afterIterPtrVal := reflect.New(toType)
  101. afterIterPtr := afterIterPtrVal.Interface()
  102. err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
  103. if err != nil {
  104. t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
  105. err, indent(jbIter, " "))
  106. }
  107. afterStd := afterStdPtrVal.Elem().Interface()
  108. afterIter := afterIterPtrVal.Elem().Interface()
  109. if fingerprint(afterStd) != fingerprint(afterIter) {
  110. t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
  111. dump(afterStd), dump(afterIter), indent(jbIter, " "))
  112. }
  113. }
  114. }
  115. }
  116. const indentStr = "> "
  117. func fingerprint(obj interface{}) string {
  118. c := spew.ConfigState{
  119. SortKeys: true,
  120. SpewKeys: true,
  121. }
  122. return c.Sprintf("%v", obj)
  123. }
  124. func dump(obj interface{}) string {
  125. cfg := spew.ConfigState{
  126. Indent: indentStr,
  127. }
  128. return cfg.Sdump(obj)
  129. }
  130. func indent(src []byte, prefix string) string {
  131. var buf bytes.Buffer
  132. err := json.Indent(&buf, src, prefix, indentStr)
  133. if err != nil {
  134. return fmt.Sprintf("!!! %v", err)
  135. }
  136. return buf.String()
  137. }