1
2
3
4
5
6
7 package jsonopts_test
8
9 import (
10 "reflect"
11 "testing"
12
13 "encoding/json/internal/jsonflags"
14 . "encoding/json/internal/jsonopts"
15 "encoding/json/jsontext"
16 "encoding/json/v2"
17 )
18
19 func makeFlags(f ...jsonflags.Bools) (fs jsonflags.Flags) {
20 for _, f := range f {
21 fs.Set(f)
22 }
23 return fs
24 }
25
26 func TestJoin(t *testing.T) {
27 tests := []struct {
28 in Options
29 want *Struct
30 }{{
31 in: jsonflags.AllowInvalidUTF8 | 1,
32 want: &Struct{Flags: makeFlags(jsonflags.AllowInvalidUTF8 | 1)},
33 }, {
34 in: jsonflags.Multiline | 0,
35 want: &Struct{
36 Flags: makeFlags(jsonflags.AllowInvalidUTF8|1, jsonflags.Multiline|0)},
37 }, {
38 in: Indent("\t"),
39 want: &Struct{
40 Flags: makeFlags(jsonflags.AllowInvalidUTF8 | jsonflags.Multiline | jsonflags.Indent | 1),
41 CoderValues: CoderValues{Indent: "\t"},
42 },
43 }, {
44 in: &Struct{
45 Flags: makeFlags(jsonflags.Multiline|jsonflags.EscapeForJS|0, jsonflags.AllowInvalidUTF8|1),
46 },
47 want: &Struct{
48 Flags: makeFlags(jsonflags.AllowInvalidUTF8|jsonflags.Indent|1, jsonflags.Multiline|jsonflags.EscapeForJS|0),
49 CoderValues: CoderValues{Indent: "\t"},
50 },
51 }, {
52 in: &DefaultOptionsV1,
53 want: func() *Struct {
54 v1 := DefaultOptionsV1
55 v1.Flags.Set(jsonflags.Indent | 1)
56 v1.Flags.Set(jsonflags.Multiline | 0)
57 v1.Indent = "\t"
58 return &v1
59 }(),
60 }, {
61 in: &DefaultOptionsV2,
62 want: func() *Struct {
63 v2 := DefaultOptionsV2
64 v2.Flags.Set(jsonflags.Indent | 1)
65 v2.Flags.Set(jsonflags.Multiline | 0)
66 v2.Indent = "\t"
67 return &v2
68 }(),
69 }, {
70 in: jsontext.WithIndentPrefix(" "),
71 want: func() *Struct {
72 v2 := DefaultOptionsV2
73 v2.Flags.Set(jsonflags.Indent | 1)
74 v2.Flags.Set(jsonflags.IndentPrefix | 1)
75 v2.Flags.Set(jsonflags.Multiline | 1)
76 v2.Indent = "\t"
77 v2.IndentPrefix = " "
78 return &v2
79 }(),
80 }, {
81 in: &Struct{
82 Flags: jsonflags.Flags{
83 Presence: uint64(jsonflags.Deterministic | jsonflags.Indent | jsonflags.IndentPrefix),
84 Values: uint64(jsonflags.Indent | jsonflags.IndentPrefix),
85 },
86 CoderValues: CoderValues{Indent: " ", IndentPrefix: " "},
87 },
88 want: func() *Struct {
89 v2 := DefaultOptionsV2
90 v2.Flags.Set(jsonflags.Indent | 1)
91 v2.Flags.Set(jsonflags.IndentPrefix | 1)
92 v2.Flags.Set(jsonflags.Multiline | 1)
93 v2.Indent = " "
94 v2.IndentPrefix = " "
95 return &v2
96 }(),
97 }, {
98 in: ExperimentalSupportFormatTag(true),
99 want: func() *Struct {
100 v2 := DefaultOptionsV2
101 v2.Flags.Set(jsonflags.Indent | 1)
102 v2.Flags.Set(jsonflags.IndentPrefix | 1)
103 v2.Flags.Set(jsonflags.Multiline | 1)
104 v2.Flags.Set(jsonflags.FormatTagSupported | 1)
105 v2.Indent = " "
106 v2.IndentPrefix = " "
107 return &v2
108 }(),
109 }, {
110 in: &Struct{Flags: jsonflags.Flags{Presence: uint64(jsonflags.FormatTagSupported)}},
111 want: func() *Struct {
112 v2 := DefaultOptionsV2
113 v2.Flags.Set(jsonflags.Indent | 1)
114 v2.Flags.Set(jsonflags.IndentPrefix | 1)
115 v2.Flags.Set(jsonflags.Multiline | 1)
116 v2.Flags.Set(jsonflags.FormatTagSupported | 0)
117 v2.Indent = " "
118 v2.IndentPrefix = " "
119 return &v2
120 }(),
121 }}
122 got := new(Struct)
123 for i, tt := range tests {
124 got.Join(tt.in)
125 if !reflect.DeepEqual(got, tt.want) {
126 t.Fatalf("%d: Join:\n\tgot: %+v\n\twant: %+v", i, got, tt.want)
127 }
128 }
129 }
130
131 func TestGet(t *testing.T) {
132 opts := &Struct{
133 Flags: makeFlags(jsonflags.Indent|jsonflags.Deterministic|jsonflags.Marshalers|jsonflags.FormatTagSupported|1, jsonflags.Multiline|0),
134 CoderValues: CoderValues{Indent: "\t"},
135 ArshalValues: ArshalValues{Marshalers: new(json.Marshalers)},
136 }
137 if v, ok := json.GetOption(nil, jsontext.AllowDuplicateNames); v || ok {
138 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
139 }
140 if v, ok := json.GetOption(jsonflags.AllowInvalidUTF8|0, jsontext.AllowDuplicateNames); v || ok {
141 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
142 }
143 if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|0, jsontext.AllowDuplicateNames); v || !ok {
144 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, true)", v, ok)
145 }
146 if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|1, jsontext.AllowDuplicateNames); !v || !ok {
147 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (true, true)", v, ok)
148 }
149 if v, ok := json.GetOption(Indent(""), jsontext.AllowDuplicateNames); v || ok {
150 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
151 }
152 if v, ok := json.GetOption(Indent(" "), jsontext.WithIndent); v != " " || !ok {
153 t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want (" ", true)`, v, ok)
154 }
155 if v, ok := json.GetOption(jsonflags.AllowDuplicateNames|1, jsontext.WithIndent); v != "" || ok {
156 t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want ("", false)`, v, ok)
157 }
158 if v, ok := json.GetOption(opts, jsontext.AllowDuplicateNames); v || ok {
159 t.Errorf("GetOption(..., AllowDuplicateNames) = (%v, %v), want (false, false)", v, ok)
160 }
161 if v, ok := json.GetOption(opts, json.Deterministic); !v || !ok {
162 t.Errorf("GetOption(..., Deterministic) = (%v, %v), want (true, true)", v, ok)
163 }
164 if v, ok := json.GetOption(opts, jsontext.Multiline); v || !ok {
165 t.Errorf("GetOption(..., Multiline) = (%v, %v), want (false, true)", v, ok)
166 }
167 if v, ok := json.GetOption(opts, jsontext.AllowInvalidUTF8); v || ok {
168 t.Errorf("GetOption(..., AllowInvalidUTF8) = (%v, %v), want (false, false)", v, ok)
169 }
170 if v, ok := json.GetOption(opts, jsontext.WithIndent); v != "\t" || !ok {
171 t.Errorf(`GetOption(..., WithIndent) = (%q, %v), want ("\t", true)`, v, ok)
172 }
173 if v, ok := json.GetOption(opts, jsontext.WithIndentPrefix); v != "" || ok {
174 t.Errorf(`GetOption(..., WithIndentPrefix) = (%q, %v), want ("", false)`, v, ok)
175 }
176 if v, ok := json.GetOption(opts, json.WithMarshalers); v == nil || !ok {
177 t.Errorf(`GetOption(..., WithMarshalers) = (%v, %v), want (non-nil, true)`, v, ok)
178 }
179 if v, ok := json.GetOption(opts, json.WithUnmarshalers); v != nil || ok {
180 t.Errorf(`GetOption(..., WithUnmarshalers) = (%v, %v), want (nil, false)`, v, ok)
181 }
182 if v, ok := json.GetOption(json.DefaultOptionsV2(), json.WithMarshalers); v != nil || ok {
183 t.Errorf(`GetOption(..., WithMarshalers) = (%v, %v), want (nil, false)`, v, ok)
184 }
185 if v, ok := json.GetOption(opts, ExperimentalSupportFormatTag); !v || !ok {
186 t.Errorf(`GetOption(..., ExperimentalSupportFormatTag) = (%v, %v), want (true, true)`, v, ok)
187 }
188 if v, ok := json.GetOption(json.DefaultOptionsV2(), ExperimentalSupportFormatTag); v || ok {
189 t.Errorf(`GetOption(..., ExperimentalSupportFormatTag) = (%v, %v), want (false, false)`, v, ok)
190 }
191 }
192
193 var sink struct {
194 Bool bool
195 String string
196 Marshalers *json.Marshalers
197 }
198
199 func BenchmarkGetBool(b *testing.B) {
200 b.ReportAllocs()
201 opts := json.DefaultOptionsV2()
202 for range b.N {
203 sink.Bool, sink.Bool = json.GetOption(opts, jsontext.AllowDuplicateNames)
204 }
205 }
206
207 func BenchmarkGetIndent(b *testing.B) {
208 b.ReportAllocs()
209 opts := json.DefaultOptionsV2()
210 for range b.N {
211 sink.String, sink.Bool = json.GetOption(opts, jsontext.WithIndent)
212 }
213 }
214
215 func BenchmarkGetMarshalers(b *testing.B) {
216 b.ReportAllocs()
217 opts := json.JoinOptions(json.DefaultOptionsV2(), json.WithMarshalers(nil))
218 for range b.N {
219 sink.Marshalers, sink.Bool = json.GetOption(opts, json.WithMarshalers)
220 }
221 }
222
View as plain text