type_test.go 4.8 KB

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