type_test.go 4.6 KB

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