|
|
@@ -0,0 +1,94 @@
|
|
|
+package test
|
|
|
+
|
|
|
+import (
|
|
|
+ "testing"
|
|
|
+ "reflect"
|
|
|
+ "fmt"
|
|
|
+ "github.com/google/gofuzz"
|
|
|
+ "strings"
|
|
|
+ "github.com/json-iterator/go"
|
|
|
+ "encoding/json"
|
|
|
+ "bytes"
|
|
|
+ "github.com/davecgh/go-spew/spew"
|
|
|
+)
|
|
|
+
|
|
|
+var testCases []interface{}
|
|
|
+
|
|
|
+func Test(t *testing.T) {
|
|
|
+ for _, testCase := range testCases {
|
|
|
+ valType := reflect.TypeOf(testCase).Elem()
|
|
|
+ fz := fuzz.New().MaxDepth(10).NilChance(0.3)
|
|
|
+ for i := 0; i < 100; i++ {
|
|
|
+ beforePtrVal := reflect.New(valType)
|
|
|
+ beforePtr := beforePtrVal.Interface()
|
|
|
+ fz.Fuzz(beforePtr)
|
|
|
+ before := beforePtrVal.Elem().Interface()
|
|
|
+
|
|
|
+ jbStd, err := json.Marshal(before)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to marshal with stdlib: %v", err)
|
|
|
+ }
|
|
|
+ if len(strings.TrimSpace(string(jbStd))) == 0 {
|
|
|
+ t.Fatal("stdlib marshal produced empty result and no error")
|
|
|
+ }
|
|
|
+ jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to marshal with jsoniter: %v", err)
|
|
|
+ }
|
|
|
+ if len(strings.TrimSpace(string(jbIter))) == 0 {
|
|
|
+ t.Fatal("jsoniter marshal produced empty result and no error")
|
|
|
+ }
|
|
|
+ if string(jbStd) != string(jbIter) {
|
|
|
+ t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
|
|
|
+ indent(jbStd, " "), indent(jbIter, " "), dump(before))
|
|
|
+ }
|
|
|
+
|
|
|
+ afterStdPtrVal := reflect.New(valType)
|
|
|
+ afterStdPtr := afterStdPtrVal.Interface()
|
|
|
+ err = json.Unmarshal(jbIter, afterStdPtr)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to unmarshal with stdlib: %v\nvia:\n %s",
|
|
|
+ err, indent(jbIter, " "))
|
|
|
+ }
|
|
|
+ afterIterPtrVal := reflect.New(valType)
|
|
|
+ afterIterPtr := afterIterPtrVal.Interface()
|
|
|
+ err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, afterIterPtr)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to unmarshal with jsoniter: %v\nvia:\n %s",
|
|
|
+ err, indent(jbIter, " "))
|
|
|
+ }
|
|
|
+ afterStd := afterStdPtrVal.Elem().Interface()
|
|
|
+ afterIter := afterIterPtrVal.Elem().Interface()
|
|
|
+ if fingerprint(afterStd) != fingerprint(afterIter) {
|
|
|
+ t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
|
|
|
+ dump(afterStd), dump(afterIter), indent(jbIter, " "))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const indentStr = "> "
|
|
|
+
|
|
|
+func fingerprint(obj interface{}) string {
|
|
|
+ c := spew.ConfigState{
|
|
|
+ SortKeys: true,
|
|
|
+ SpewKeys: true,
|
|
|
+ }
|
|
|
+ return c.Sprintf("%v", obj)
|
|
|
+}
|
|
|
+
|
|
|
+func dump(obj interface{}) string {
|
|
|
+ cfg := spew.ConfigState{
|
|
|
+ Indent: indentStr,
|
|
|
+ }
|
|
|
+ return cfg.Sdump(obj)
|
|
|
+}
|
|
|
+
|
|
|
+func indent(src []byte, prefix string) string {
|
|
|
+ var buf bytes.Buffer
|
|
|
+ err := json.Indent(&buf, src, prefix, indentStr)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Sprintf("!!! %v", err)
|
|
|
+ }
|
|
|
+ return buf.String()
|
|
|
+}
|