Skip to content

Commit 5bb7a1f

Browse files
committed
Add output test for 'string' tag
1 parent c2c9981 commit 5bb7a1f

File tree

22 files changed

+1716
-0
lines changed

22 files changed

+1716
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package test
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
"testing"
9+
10+
"github.com/davecgh/go-spew/spew"
11+
fuzz "github.com/google/gofuzz"
12+
jsoniter "github.com/json-iterator/go"
13+
)
14+
15+
func Test_Roundtrip(t *testing.T) {
16+
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
17+
for i := 0; i < 1000; i++ {
18+
var before T
19+
fz.Fuzz(&before)
20+
21+
jbStd, err := json.Marshal(before)
22+
if err != nil {
23+
t.Fatalf("failed to marshal with stdlib: %v", err)
24+
}
25+
if len(strings.TrimSpace(string(jbStd))) == 0 {
26+
t.Fatal("stdlib marshal produced empty result and no error")
27+
}
28+
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
29+
if err != nil {
30+
t.Fatalf("failed to marshal with jsoniter: %v", err)
31+
}
32+
if len(strings.TrimSpace(string(jbIter))) == 0 {
33+
t.Fatal("jsoniter marshal produced empty result and no error")
34+
}
35+
if string(jbStd) != string(jbIter) {
36+
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
37+
indent(jbStd, " "), indent(jbIter, " "), dump(before))
38+
}
39+
40+
var afterStd T
41+
err = json.Unmarshal(jbIter, &afterStd)
42+
if err != nil {
43+
t.Fatalf("failed to unmarshal with stdlib: %v", err)
44+
}
45+
var afterIter T
46+
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
47+
if err != nil {
48+
t.Fatalf("failed to unmarshal with jsoniter: %v", err)
49+
}
50+
if fingerprint(afterStd) != fingerprint(afterIter) {
51+
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
52+
dump(afterStd), dump(afterIter), indent(jbIter, " "))
53+
}
54+
}
55+
}
56+
57+
const indentStr = "> "
58+
59+
func fingerprint(obj interface{}) string {
60+
c := spew.ConfigState{
61+
SortKeys: true,
62+
SpewKeys: true,
63+
}
64+
return c.Sprintf("%v", obj)
65+
}
66+
67+
func dump(obj interface{}) string {
68+
cfg := spew.ConfigState{
69+
Indent: indentStr,
70+
}
71+
return cfg.Sdump(obj)
72+
}
73+
74+
func indent(src []byte, prefix string) string {
75+
var buf bytes.Buffer
76+
err := json.Indent(&buf, src, prefix, indentStr)
77+
if err != nil {
78+
return fmt.Sprintf("!!! %v", err)
79+
}
80+
return buf.String()
81+
}
82+
83+
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
84+
t.ReportAllocs()
85+
t.ResetTimer()
86+
87+
var obj T
88+
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
89+
fz.Fuzz(&obj)
90+
for i := 0; i < t.N; i++ {
91+
jb, err := fn(obj)
92+
if err != nil {
93+
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
94+
}
95+
_ = jb
96+
}
97+
}
98+
99+
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
100+
t.ReportAllocs()
101+
t.ResetTimer()
102+
103+
var before T
104+
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
105+
fz.Fuzz(&before)
106+
jb, err := json.Marshal(before)
107+
if err != nil {
108+
t.Fatalf("failed to marshal: %v", err)
109+
}
110+
111+
for i := 0; i < t.N; i++ {
112+
var after T
113+
err = fn(jb, &after)
114+
if err != nil {
115+
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
116+
}
117+
}
118+
}
119+
120+
func BenchmarkStandardMarshal(t *testing.B) {
121+
benchmarkMarshal(t, "stdlib", json.Marshal)
122+
}
123+
124+
func BenchmarkStandardUnmarshal(t *testing.B) {
125+
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
126+
}
127+
128+
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
129+
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
130+
}
131+
132+
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
133+
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
134+
}
135+
136+
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
137+
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
138+
}
139+
140+
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
141+
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
142+
}
143+
144+
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
145+
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
146+
}
147+
148+
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
149+
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
150+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package test
2+
3+
type T struct {
4+
F1 bool `json:"F1"`
5+
F2 bool `json:"F2,string"`
6+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package test
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"strings"
8+
"testing"
9+
10+
"github.com/davecgh/go-spew/spew"
11+
fuzz "github.com/google/gofuzz"
12+
jsoniter "github.com/json-iterator/go"
13+
)
14+
15+
func Test_Roundtrip(t *testing.T) {
16+
fz := fuzz.New().MaxDepth(10).NilChance(0.3)
17+
for i := 0; i < 1000; i++ {
18+
var before T
19+
fz.Fuzz(&before)
20+
21+
jbStd, err := json.Marshal(before)
22+
if err != nil {
23+
t.Fatalf("failed to marshal with stdlib: %v", err)
24+
}
25+
if len(strings.TrimSpace(string(jbStd))) == 0 {
26+
t.Fatal("stdlib marshal produced empty result and no error")
27+
}
28+
jbIter, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(before)
29+
if err != nil {
30+
t.Fatalf("failed to marshal with jsoniter: %v", err)
31+
}
32+
if len(strings.TrimSpace(string(jbIter))) == 0 {
33+
t.Fatal("jsoniter marshal produced empty result and no error")
34+
}
35+
if string(jbStd) != string(jbIter) {
36+
t.Fatalf("marshal expected:\n %s\ngot:\n %s\nobj:\n %s",
37+
indent(jbStd, " "), indent(jbIter, " "), dump(before))
38+
}
39+
40+
var afterStd T
41+
err = json.Unmarshal(jbIter, &afterStd)
42+
if err != nil {
43+
t.Fatalf("failed to unmarshal with stdlib: %v", err)
44+
}
45+
var afterIter T
46+
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(jbIter, &afterIter)
47+
if err != nil {
48+
t.Fatalf("failed to unmarshal with jsoniter: %v", err)
49+
}
50+
if fingerprint(afterStd) != fingerprint(afterIter) {
51+
t.Fatalf("unmarshal expected:\n %s\ngot:\n %s\nvia:\n %s",
52+
dump(afterStd), dump(afterIter), indent(jbIter, " "))
53+
}
54+
}
55+
}
56+
57+
const indentStr = "> "
58+
59+
func fingerprint(obj interface{}) string {
60+
c := spew.ConfigState{
61+
SortKeys: true,
62+
SpewKeys: true,
63+
}
64+
return c.Sprintf("%v", obj)
65+
}
66+
67+
func dump(obj interface{}) string {
68+
cfg := spew.ConfigState{
69+
Indent: indentStr,
70+
}
71+
return cfg.Sdump(obj)
72+
}
73+
74+
func indent(src []byte, prefix string) string {
75+
var buf bytes.Buffer
76+
err := json.Indent(&buf, src, prefix, indentStr)
77+
if err != nil {
78+
return fmt.Sprintf("!!! %v", err)
79+
}
80+
return buf.String()
81+
}
82+
83+
func benchmarkMarshal(t *testing.B, name string, fn func(interface{}) ([]byte, error)) {
84+
t.ReportAllocs()
85+
t.ResetTimer()
86+
87+
var obj T
88+
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
89+
fz.Fuzz(&obj)
90+
for i := 0; i < t.N; i++ {
91+
jb, err := fn(obj)
92+
if err != nil {
93+
t.Fatalf("%s failed to marshal:\n input: %s\n error: %v", name, dump(obj), err)
94+
}
95+
_ = jb
96+
}
97+
}
98+
99+
func benchmarkUnmarshal(t *testing.B, name string, fn func(data []byte, v interface{}) error) {
100+
t.ReportAllocs()
101+
t.ResetTimer()
102+
103+
var before T
104+
fz := fuzz.NewWithSeed(0).MaxDepth(10).NilChance(0.3)
105+
fz.Fuzz(&before)
106+
jb, err := json.Marshal(before)
107+
if err != nil {
108+
t.Fatalf("failed to marshal: %v", err)
109+
}
110+
111+
for i := 0; i < t.N; i++ {
112+
var after T
113+
err = fn(jb, &after)
114+
if err != nil {
115+
t.Fatalf("%s failed to unmarshal:\n input: %q\n error: %v", name, string(jb), err)
116+
}
117+
}
118+
}
119+
120+
func BenchmarkStandardMarshal(t *testing.B) {
121+
benchmarkMarshal(t, "stdlib", json.Marshal)
122+
}
123+
124+
func BenchmarkStandardUnmarshal(t *testing.B) {
125+
benchmarkUnmarshal(t, "stdlib", json.Unmarshal)
126+
}
127+
128+
func BenchmarkJSONIterMarshalFastest(t *testing.B) {
129+
benchmarkMarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Marshal)
130+
}
131+
132+
func BenchmarkJSONIterUnmarshalFastest(t *testing.B) {
133+
benchmarkUnmarshal(t, "jsoniter-fastest", jsoniter.ConfigFastest.Unmarshal)
134+
}
135+
136+
func BenchmarkJSONIterMarshalDefault(t *testing.B) {
137+
benchmarkMarshal(t, "jsoniter-default", jsoniter.Marshal)
138+
}
139+
140+
func BenchmarkJSONIterUnmarshalDefault(t *testing.B) {
141+
benchmarkUnmarshal(t, "jsoniter-default", jsoniter.Unmarshal)
142+
}
143+
144+
func BenchmarkJSONIterMarshalCompatible(t *testing.B) {
145+
benchmarkMarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Marshal)
146+
}
147+
148+
func BenchmarkJSONIterUnmarshalCompatible(t *testing.B) {
149+
benchmarkUnmarshal(t, "jsoniter-compat", jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal)
150+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package test
2+
3+
type T struct {
4+
F1 byte `json:"F1"`
5+
F2 byte `json:"F2,string"`
6+
}

0 commit comments

Comments
 (0)