From e16ee7f8ac61dcf54a03a3ea1125701cef403211 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 27 Jun 2017 11:41:17 +0100 Subject: [PATCH] Add output tests for structs of slices and maps --- .../maps/builtins/float32/json_test.go | 139 ++++++++++++++++++ .../structs/maps/builtins/float32/types.go | 5 + .../structs/maps/builtins/int32/json_test.go | 139 ++++++++++++++++++ .../structs/maps/builtins/int32/types.go | 5 + .../structs/maps/builtins/string/json_test.go | 139 ++++++++++++++++++ .../structs/maps/builtins/string/types.go | 5 + .../maps/builtins/string_alias/json_test.go | 139 ++++++++++++++++++ .../maps/builtins/string_alias/types.go | 9 ++ .../maps/builtins/strings/json_test.go | 139 ++++++++++++++++++ .../structs/maps/builtins/strings/types.go | 7 + .../maps/pointers/float32/json_test.go | 139 ++++++++++++++++++ .../structs/maps/pointers/float32/types.go | 5 + .../structs/maps/pointers/int32/json_test.go | 139 ++++++++++++++++++ .../structs/maps/pointers/int32/types.go | 5 + .../structs/maps/pointers/string/json_test.go | 139 ++++++++++++++++++ .../structs/maps/pointers/string/types.go | 5 + .../maps/pointers/string_alias/json_test.go | 139 ++++++++++++++++++ .../maps/pointers/string_alias/types.go | 9 ++ .../maps/pointers/strings/json_test.go | 139 ++++++++++++++++++ .../structs/maps/pointers/strings/types.go | 7 + .../structs/maps/structs/empty/json_test.go | 139 ++++++++++++++++++ .../structs/maps/structs/empty/types.go | 5 + .../maps/structs/float32s/json_test.go | 139 ++++++++++++++++++ .../structs/maps/structs/float32s/types.go | 9 ++ .../structs/maps/structs/int32s/json_test.go | 139 ++++++++++++++++++ .../structs/maps/structs/int32s/types.go | 9 ++ .../maps/structs/ptr_to_strings/json_test.go | 139 ++++++++++++++++++ .../maps/structs/ptr_to_strings/types.go | 9 ++ .../structs/maps/structs/strings/json_test.go | 139 ++++++++++++++++++ .../structs/maps/structs/strings/types.go | 9 ++ .../slices/builtins/float32/json_test.go | 139 ++++++++++++++++++ .../structs/slices/builtins/float32/types.go | 5 + .../slices/builtins/int32/json_test.go | 139 ++++++++++++++++++ .../structs/slices/builtins/int32/types.go | 5 + .../slices/builtins/string/json_test.go | 139 ++++++++++++++++++ .../structs/slices/builtins/string/types.go | 5 + .../slices/builtins/string_alias/json_test.go | 139 ++++++++++++++++++ .../slices/builtins/string_alias/types.go | 9 ++ .../slices/builtins/strings/json_test.go | 139 ++++++++++++++++++ .../structs/slices/builtins/strings/types.go | 7 + .../slices/pointers/float32/json_test.go | 139 ++++++++++++++++++ .../structs/slices/pointers/float32/types.go | 5 + .../slices/pointers/int32/json_test.go | 139 ++++++++++++++++++ .../structs/slices/pointers/int32/types.go | 5 + .../slices/pointers/string/json_test.go | 139 ++++++++++++++++++ .../structs/slices/pointers/string/types.go | 5 + .../slices/pointers/string_alias/json_test.go | 139 ++++++++++++++++++ .../slices/pointers/string_alias/types.go | 9 ++ .../slices/pointers/strings/json_test.go | 139 ++++++++++++++++++ .../structs/slices/pointers/strings/types.go | 7 + .../structs/slices/structs/empty/json_test.go | 139 ++++++++++++++++++ .../structs/slices/structs/empty/types.go | 5 + .../slices/structs/float32s/json_test.go | 139 ++++++++++++++++++ .../structs/slices/structs/float32s/types.go | 9 ++ .../slices/structs/int32s/json_test.go | 139 ++++++++++++++++++ .../structs/slices/structs/int32s/types.go | 9 ++ .../structs/ptr_to_strings/json_test.go | 139 ++++++++++++++++++ .../slices/structs/ptr_to_strings/types.go | 9 ++ .../slices/structs/strings/json_test.go | 139 ++++++++++++++++++ .../structs/slices/structs/strings/types.go | 9 ++ 60 files changed, 4376 insertions(+) create mode 100644 output_tests/structs/maps/builtins/float32/json_test.go create mode 100644 output_tests/structs/maps/builtins/float32/types.go create mode 100644 output_tests/structs/maps/builtins/int32/json_test.go create mode 100644 output_tests/structs/maps/builtins/int32/types.go create mode 100644 output_tests/structs/maps/builtins/string/json_test.go create mode 100644 output_tests/structs/maps/builtins/string/types.go create mode 100644 output_tests/structs/maps/builtins/string_alias/json_test.go create mode 100644 output_tests/structs/maps/builtins/string_alias/types.go create mode 100644 output_tests/structs/maps/builtins/strings/json_test.go create mode 100644 output_tests/structs/maps/builtins/strings/types.go create mode 100644 output_tests/structs/maps/pointers/float32/json_test.go create mode 100644 output_tests/structs/maps/pointers/float32/types.go create mode 100644 output_tests/structs/maps/pointers/int32/json_test.go create mode 100644 output_tests/structs/maps/pointers/int32/types.go create mode 100644 output_tests/structs/maps/pointers/string/json_test.go create mode 100644 output_tests/structs/maps/pointers/string/types.go create mode 100644 output_tests/structs/maps/pointers/string_alias/json_test.go create mode 100644 output_tests/structs/maps/pointers/string_alias/types.go create mode 100644 output_tests/structs/maps/pointers/strings/json_test.go create mode 100644 output_tests/structs/maps/pointers/strings/types.go create mode 100644 output_tests/structs/maps/structs/empty/json_test.go create mode 100644 output_tests/structs/maps/structs/empty/types.go create mode 100644 output_tests/structs/maps/structs/float32s/json_test.go create mode 100644 output_tests/structs/maps/structs/float32s/types.go create mode 100644 output_tests/structs/maps/structs/int32s/json_test.go create mode 100644 output_tests/structs/maps/structs/int32s/types.go create mode 100644 output_tests/structs/maps/structs/ptr_to_strings/json_test.go create mode 100644 output_tests/structs/maps/structs/ptr_to_strings/types.go create mode 100644 output_tests/structs/maps/structs/strings/json_test.go create mode 100644 output_tests/structs/maps/structs/strings/types.go create mode 100644 output_tests/structs/slices/builtins/float32/json_test.go create mode 100644 output_tests/structs/slices/builtins/float32/types.go create mode 100644 output_tests/structs/slices/builtins/int32/json_test.go create mode 100644 output_tests/structs/slices/builtins/int32/types.go create mode 100644 output_tests/structs/slices/builtins/string/json_test.go create mode 100644 output_tests/structs/slices/builtins/string/types.go create mode 100644 output_tests/structs/slices/builtins/string_alias/json_test.go create mode 100644 output_tests/structs/slices/builtins/string_alias/types.go create mode 100644 output_tests/structs/slices/builtins/strings/json_test.go create mode 100644 output_tests/structs/slices/builtins/strings/types.go create mode 100644 output_tests/structs/slices/pointers/float32/json_test.go create mode 100644 output_tests/structs/slices/pointers/float32/types.go create mode 100644 output_tests/structs/slices/pointers/int32/json_test.go create mode 100644 output_tests/structs/slices/pointers/int32/types.go create mode 100644 output_tests/structs/slices/pointers/string/json_test.go create mode 100644 output_tests/structs/slices/pointers/string/types.go create mode 100644 output_tests/structs/slices/pointers/string_alias/json_test.go create mode 100644 output_tests/structs/slices/pointers/string_alias/types.go create mode 100644 output_tests/structs/slices/pointers/strings/json_test.go create mode 100644 output_tests/structs/slices/pointers/strings/types.go create mode 100644 output_tests/structs/slices/structs/empty/json_test.go create mode 100644 output_tests/structs/slices/structs/empty/types.go create mode 100644 output_tests/structs/slices/structs/float32s/json_test.go create mode 100644 output_tests/structs/slices/structs/float32s/types.go create mode 100644 output_tests/structs/slices/structs/int32s/json_test.go create mode 100644 output_tests/structs/slices/structs/int32s/types.go create mode 100644 output_tests/structs/slices/structs/ptr_to_strings/json_test.go create mode 100644 output_tests/structs/slices/structs/ptr_to_strings/types.go create mode 100644 output_tests/structs/slices/structs/strings/json_test.go create mode 100644 output_tests/structs/slices/structs/strings/types.go diff --git a/output_tests/structs/maps/builtins/float32/json_test.go b/output_tests/structs/maps/builtins/float32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/builtins/float32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/builtins/float32/types.go b/output_tests/structs/maps/builtins/float32/types.go new file mode 100644 index 0000000..4cf8288 --- /dev/null +++ b/output_tests/structs/maps/builtins/float32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]float32 +} diff --git a/output_tests/structs/maps/builtins/int32/json_test.go b/output_tests/structs/maps/builtins/int32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/builtins/int32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/builtins/int32/types.go b/output_tests/structs/maps/builtins/int32/types.go new file mode 100644 index 0000000..9bdad18 --- /dev/null +++ b/output_tests/structs/maps/builtins/int32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]int32 +} diff --git a/output_tests/structs/maps/builtins/string/json_test.go b/output_tests/structs/maps/builtins/string/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/builtins/string/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/builtins/string/types.go b/output_tests/structs/maps/builtins/string/types.go new file mode 100644 index 0000000..8e3cf1f --- /dev/null +++ b/output_tests/structs/maps/builtins/string/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]string +} diff --git a/output_tests/structs/maps/builtins/string_alias/json_test.go b/output_tests/structs/maps/builtins/string_alias/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/builtins/string_alias/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/builtins/string_alias/types.go b/output_tests/structs/maps/builtins/string_alias/types.go new file mode 100644 index 0000000..e2ecc99 --- /dev/null +++ b/output_tests/structs/maps/builtins/string_alias/types.go @@ -0,0 +1,9 @@ +package test + +type A1 string +type A2 map[string]A1 + +type T struct { + F1 map[string]A1 + F2 A2 +} diff --git a/output_tests/structs/maps/builtins/strings/json_test.go b/output_tests/structs/maps/builtins/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/builtins/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/builtins/strings/types.go b/output_tests/structs/maps/builtins/strings/types.go new file mode 100644 index 0000000..312dcc4 --- /dev/null +++ b/output_tests/structs/maps/builtins/strings/types.go @@ -0,0 +1,7 @@ +package test + +type T struct { + F1 map[string]string + F2 map[string]string + F3 map[string]string +} diff --git a/output_tests/structs/maps/pointers/float32/json_test.go b/output_tests/structs/maps/pointers/float32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/pointers/float32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/pointers/float32/types.go b/output_tests/structs/maps/pointers/float32/types.go new file mode 100644 index 0000000..9e24661 --- /dev/null +++ b/output_tests/structs/maps/pointers/float32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]*float32 +} diff --git a/output_tests/structs/maps/pointers/int32/json_test.go b/output_tests/structs/maps/pointers/int32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/pointers/int32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/pointers/int32/types.go b/output_tests/structs/maps/pointers/int32/types.go new file mode 100644 index 0000000..dab3575 --- /dev/null +++ b/output_tests/structs/maps/pointers/int32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]*int32 +} diff --git a/output_tests/structs/maps/pointers/string/json_test.go b/output_tests/structs/maps/pointers/string/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/pointers/string/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/pointers/string/types.go b/output_tests/structs/maps/pointers/string/types.go new file mode 100644 index 0000000..bc5bc88 --- /dev/null +++ b/output_tests/structs/maps/pointers/string/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]*string +} diff --git a/output_tests/structs/maps/pointers/string_alias/json_test.go b/output_tests/structs/maps/pointers/string_alias/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/pointers/string_alias/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/pointers/string_alias/types.go b/output_tests/structs/maps/pointers/string_alias/types.go new file mode 100644 index 0000000..537d59b --- /dev/null +++ b/output_tests/structs/maps/pointers/string_alias/types.go @@ -0,0 +1,9 @@ +package test + +type A1 *string +type A2 map[string]*A1 + +type T struct { + F1 map[string]A1 + F2 A2 +} diff --git a/output_tests/structs/maps/pointers/strings/json_test.go b/output_tests/structs/maps/pointers/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/pointers/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/pointers/strings/types.go b/output_tests/structs/maps/pointers/strings/types.go new file mode 100644 index 0000000..6e0f498 --- /dev/null +++ b/output_tests/structs/maps/pointers/strings/types.go @@ -0,0 +1,7 @@ +package test + +type T struct { + F1 map[string]*string + F2 map[string]*string + F3 map[string]*string +} diff --git a/output_tests/structs/maps/structs/empty/json_test.go b/output_tests/structs/maps/structs/empty/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/structs/empty/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/structs/empty/types.go b/output_tests/structs/maps/structs/empty/types.go new file mode 100644 index 0000000..b52b62d --- /dev/null +++ b/output_tests/structs/maps/structs/empty/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F map[string]struct{} +} diff --git a/output_tests/structs/maps/structs/float32s/json_test.go b/output_tests/structs/maps/structs/float32s/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/structs/float32s/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/structs/float32s/types.go b/output_tests/structs/maps/structs/float32s/types.go new file mode 100644 index 0000000..c79868c --- /dev/null +++ b/output_tests/structs/maps/structs/float32s/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F map[string]struct { + F1 float32 + F2 float32 + F3 float32 + } +} diff --git a/output_tests/structs/maps/structs/int32s/json_test.go b/output_tests/structs/maps/structs/int32s/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/structs/int32s/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/structs/int32s/types.go b/output_tests/structs/maps/structs/int32s/types.go new file mode 100644 index 0000000..891595f --- /dev/null +++ b/output_tests/structs/maps/structs/int32s/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F map[string]struct { + F1 int32 + F2 int32 + F3 int32 + } +} diff --git a/output_tests/structs/maps/structs/ptr_to_strings/json_test.go b/output_tests/structs/maps/structs/ptr_to_strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/structs/ptr_to_strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/structs/ptr_to_strings/types.go b/output_tests/structs/maps/structs/ptr_to_strings/types.go new file mode 100644 index 0000000..c537c2d --- /dev/null +++ b/output_tests/structs/maps/structs/ptr_to_strings/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F map[string]struct { + F1 *string + F2 *string + F3 *string + } +} diff --git a/output_tests/structs/maps/structs/strings/json_test.go b/output_tests/structs/maps/structs/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/maps/structs/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/maps/structs/strings/types.go b/output_tests/structs/maps/structs/strings/types.go new file mode 100644 index 0000000..91c6d13 --- /dev/null +++ b/output_tests/structs/maps/structs/strings/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F map[string]struct { + F1 string + F2 string + F3 string + } +} diff --git a/output_tests/structs/slices/builtins/float32/json_test.go b/output_tests/structs/slices/builtins/float32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/builtins/float32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/builtins/float32/types.go b/output_tests/structs/slices/builtins/float32/types.go new file mode 100644 index 0000000..74ad37a --- /dev/null +++ b/output_tests/structs/slices/builtins/float32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []float32 +} diff --git a/output_tests/structs/slices/builtins/int32/json_test.go b/output_tests/structs/slices/builtins/int32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/builtins/int32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/builtins/int32/types.go b/output_tests/structs/slices/builtins/int32/types.go new file mode 100644 index 0000000..a5da597 --- /dev/null +++ b/output_tests/structs/slices/builtins/int32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []int32 +} diff --git a/output_tests/structs/slices/builtins/string/json_test.go b/output_tests/structs/slices/builtins/string/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/builtins/string/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/builtins/string/types.go b/output_tests/structs/slices/builtins/string/types.go new file mode 100644 index 0000000..9cd82b6 --- /dev/null +++ b/output_tests/structs/slices/builtins/string/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []string +} diff --git a/output_tests/structs/slices/builtins/string_alias/json_test.go b/output_tests/structs/slices/builtins/string_alias/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/builtins/string_alias/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/builtins/string_alias/types.go b/output_tests/structs/slices/builtins/string_alias/types.go new file mode 100644 index 0000000..726a569 --- /dev/null +++ b/output_tests/structs/slices/builtins/string_alias/types.go @@ -0,0 +1,9 @@ +package test + +type A1 string +type A2 []A1 + +type T struct { + F1 []A1 + F2 A2 +} diff --git a/output_tests/structs/slices/builtins/strings/json_test.go b/output_tests/structs/slices/builtins/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/builtins/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/builtins/strings/types.go b/output_tests/structs/slices/builtins/strings/types.go new file mode 100644 index 0000000..e7ed6ee --- /dev/null +++ b/output_tests/structs/slices/builtins/strings/types.go @@ -0,0 +1,7 @@ +package test + +type T struct { + F1 []string + F2 []string + F3 []string +} diff --git a/output_tests/structs/slices/pointers/float32/json_test.go b/output_tests/structs/slices/pointers/float32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/pointers/float32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/pointers/float32/types.go b/output_tests/structs/slices/pointers/float32/types.go new file mode 100644 index 0000000..b18535b --- /dev/null +++ b/output_tests/structs/slices/pointers/float32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []*float32 +} diff --git a/output_tests/structs/slices/pointers/int32/json_test.go b/output_tests/structs/slices/pointers/int32/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/pointers/int32/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/pointers/int32/types.go b/output_tests/structs/slices/pointers/int32/types.go new file mode 100644 index 0000000..e12c2e2 --- /dev/null +++ b/output_tests/structs/slices/pointers/int32/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []*int32 +} diff --git a/output_tests/structs/slices/pointers/string/json_test.go b/output_tests/structs/slices/pointers/string/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/pointers/string/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/pointers/string/types.go b/output_tests/structs/slices/pointers/string/types.go new file mode 100644 index 0000000..89c1317 --- /dev/null +++ b/output_tests/structs/slices/pointers/string/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []*string +} diff --git a/output_tests/structs/slices/pointers/string_alias/json_test.go b/output_tests/structs/slices/pointers/string_alias/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/pointers/string_alias/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/pointers/string_alias/types.go b/output_tests/structs/slices/pointers/string_alias/types.go new file mode 100644 index 0000000..f0e825a --- /dev/null +++ b/output_tests/structs/slices/pointers/string_alias/types.go @@ -0,0 +1,9 @@ +package test + +type A1 *string +type A2 []*A1 + +type T struct { + F1 []A1 + F2 A2 +} diff --git a/output_tests/structs/slices/pointers/strings/json_test.go b/output_tests/structs/slices/pointers/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/pointers/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/pointers/strings/types.go b/output_tests/structs/slices/pointers/strings/types.go new file mode 100644 index 0000000..adefc13 --- /dev/null +++ b/output_tests/structs/slices/pointers/strings/types.go @@ -0,0 +1,7 @@ +package test + +type T struct { + F1 []*string + F2 []*string + F3 []*string +} diff --git a/output_tests/structs/slices/structs/empty/json_test.go b/output_tests/structs/slices/structs/empty/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/structs/empty/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/structs/empty/types.go b/output_tests/structs/slices/structs/empty/types.go new file mode 100644 index 0000000..cd2c828 --- /dev/null +++ b/output_tests/structs/slices/structs/empty/types.go @@ -0,0 +1,5 @@ +package test + +type T struct { + F []struct{} +} diff --git a/output_tests/structs/slices/structs/float32s/json_test.go b/output_tests/structs/slices/structs/float32s/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/structs/float32s/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/structs/float32s/types.go b/output_tests/structs/slices/structs/float32s/types.go new file mode 100644 index 0000000..be5139c --- /dev/null +++ b/output_tests/structs/slices/structs/float32s/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F []struct { + F1 float32 + F2 float32 + F3 float32 + } +} diff --git a/output_tests/structs/slices/structs/int32s/json_test.go b/output_tests/structs/slices/structs/int32s/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/structs/int32s/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/structs/int32s/types.go b/output_tests/structs/slices/structs/int32s/types.go new file mode 100644 index 0000000..cd4b948 --- /dev/null +++ b/output_tests/structs/slices/structs/int32s/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F []struct { + F1 int32 + F2 int32 + F3 int32 + } +} diff --git a/output_tests/structs/slices/structs/ptr_to_strings/json_test.go b/output_tests/structs/slices/structs/ptr_to_strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/structs/ptr_to_strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/structs/ptr_to_strings/types.go b/output_tests/structs/slices/structs/ptr_to_strings/types.go new file mode 100644 index 0000000..876d63a --- /dev/null +++ b/output_tests/structs/slices/structs/ptr_to_strings/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F []struct { + F1 *string + F2 *string + F3 *string + } +} diff --git a/output_tests/structs/slices/structs/strings/json_test.go b/output_tests/structs/slices/structs/strings/json_test.go new file mode 100644 index 0000000..a7b1d0d --- /dev/null +++ b/output_tests/structs/slices/structs/strings/json_test.go @@ -0,0 +1,139 @@ +package test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/davecgh/go-spew/spew" + fuzz "github.com/google/gofuzz" + jsoniter "github.com/json-iterator/go" +) + +func Test_Roundtrip(t *testing.T) { + fz := fuzz.New().MaxDepth(10).NilChance(0.3) + for i := 0; i < 1000; i++ { + var before T + fz.Fuzz(&before) + + jbStd, err := json.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with stdlib: %v", err) + } + jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before) + if err != nil { + t.Errorf("failed to marshal with jsoniter: %v", err) + } + if string(jbStd) != string(jbIter) { + t.Errorf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s", + indent(jbStd, " "), indent(jbIter, " "), dump(before)) + } + + var afterStd T + err = json.Unmarshal(jbIter, &afterStd) + if err != nil { + t.Errorf("failed to unmarshal with stdlib: %v", err) + } + var afterIter T + err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter) + if err != nil { + t.Errorf("failed to unmarshal with jsoniter: %v", err) + } + if fingerprint(afterStd) != fingerprint(afterIter) { + t.Errorf("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 + json.Indent(&buf, src, prefix, indentStr) + return buf.String() +} + +func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) { + t.ReportAllocs() + t.ResetTimer() + + var obj T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&obj) + for i := 0; i < t.N; i++ { + jb, err := fn(obj) + if err != nil { + t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err) + } + _ = jb + } +} + +func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) { + t.ReportAllocs() + t.ResetTimer() + + var before T + fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3) + fz.Fuzz(&before) + jb, err := json.Marshal(before) + if err != nil { + t.Fatalf("failed to marshal: %v", err) + } + + for i := 0; i < t.N; i++ { + var after T + err = fn(jb, &after) + if err != nil { + t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err) + } + } +} + +func BenchmarkStandardMarshal(t *testing.B) { + benchmarkMarshal(t, "stdlib", json.Marshal) +} + +func BenchmarkStandardUnmarshal(t *testing.B) { + benchmarkUnmarshal(t, "stdlib", json.Unmarshal) +} + +func BenchmarkJSONIterMarshalFastest(t *testing.B) { + benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal) +} + +func BenchmarkJSONIterUnmarshalFastest(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal) +} + +func BenchmarkJSONIterMarshalDefault(t *testing.B) { + benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal) +} + +func BenchmarkJSONIterUnmarshalDefault(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal) +} + +func BenchmarkJSONIterMarshalCompatible(t *testing.B) { + benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal) +} + +func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) { + benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal) +} diff --git a/output_tests/structs/slices/structs/strings/types.go b/output_tests/structs/slices/structs/strings/types.go new file mode 100644 index 0000000..0236420 --- /dev/null +++ b/output_tests/structs/slices/structs/strings/types.go @@ -0,0 +1,9 @@ +package test + +type T struct { + F []struct { + F1 string + F2 string + F3 string + } +}