1package test
2
3import (
4	"bytes"
5	"encoding/json"
6	"github.com/json-iterator/go"
7	"github.com/stretchr/testify/assert"
8	"github.com/stretchr/testify/require"
9	"io"
10	"testing"
11)
12
13func Test_missing_object_end(t *testing.T) {
14	should := require.New(t)
15	type TestObject struct {
16		Metric string                 `json:"metric"`
17		Tags   map[string]interface{} `json:"tags"`
18	}
19	obj := TestObject{}
20	should.NotNil(jsoniter.UnmarshalFromString(`{"metric": "sys.777","tags": {"a":"123"}`, &obj))
21}
22
23func Test_missing_array_end(t *testing.T) {
24	should := require.New(t)
25	should.NotNil(jsoniter.UnmarshalFromString(`[1,2,3`, &[]int{}))
26}
27
28func Test_invalid_any(t *testing.T) {
29	should := require.New(t)
30	any := jsoniter.Get([]byte("[]"))
31	should.Equal(jsoniter.InvalidValue, any.Get(0.3).ValueType())
32	// is nil correct ?
33	should.Equal(nil, any.Get(0.3).GetInterface())
34
35	any = any.Get(0.3)
36	should.Equal(false, any.ToBool())
37	should.Equal(int(0), any.ToInt())
38	should.Equal(int32(0), any.ToInt32())
39	should.Equal(int64(0), any.ToInt64())
40	should.Equal(uint(0), any.ToUint())
41	should.Equal(uint32(0), any.ToUint32())
42	should.Equal(uint64(0), any.ToUint64())
43	should.Equal(float32(0), any.ToFloat32())
44	should.Equal(float64(0), any.ToFloat64())
45	should.Equal("", any.ToString())
46
47	should.Equal(jsoniter.InvalidValue, any.Get(0.1).Get(1).ValueType())
48}
49
50func Test_invalid_struct_input(t *testing.T) {
51	should := require.New(t)
52	type TestObject struct{}
53	input := []byte{54, 141, 30}
54	obj := TestObject{}
55	should.NotNil(jsoniter.Unmarshal(input, &obj))
56}
57
58func Test_invalid_slice_input(t *testing.T) {
59	should := require.New(t)
60	type TestObject struct{}
61	input := []byte{93}
62	obj := []string{}
63	should.NotNil(jsoniter.Unmarshal(input, &obj))
64}
65
66func Test_invalid_array_input(t *testing.T) {
67	should := require.New(t)
68	type TestObject struct{}
69	input := []byte{93}
70	obj := [0]string{}
71	should.NotNil(jsoniter.Unmarshal(input, &obj))
72}
73
74func Test_invalid_float(t *testing.T) {
75	inputs := []string{
76		`1.e1`, // dot without following digit
77		`1.`,   // dot can not be the last char
78		``,     // empty number
79		`01`,   // extra leading zero
80		`-`,    // negative without digit
81		`--`,   // double negative
82		`--2`,  // double negative
83	}
84	for _, input := range inputs {
85		t.Run(input, func(t *testing.T) {
86			should := require.New(t)
87			iter := jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
88			iter.Skip()
89			should.NotEqual(io.EOF, iter.Error)
90			should.NotNil(iter.Error)
91			v := float64(0)
92			should.NotNil(json.Unmarshal([]byte(input), &v))
93			iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
94			iter.ReadFloat64()
95			should.NotEqual(io.EOF, iter.Error)
96			should.NotNil(iter.Error)
97			iter = jsoniter.ParseString(jsoniter.ConfigDefault, input+",")
98			iter.ReadFloat32()
99			should.NotEqual(io.EOF, iter.Error)
100			should.NotNil(iter.Error)
101		})
102	}
103}
104
105func Test_chan(t *testing.T) {
106	t.Skip("do not support chan")
107
108	type TestObject struct {
109		MyChan  chan bool
110		MyField int
111	}
112
113	should := require.New(t)
114	obj := TestObject{}
115	str, err := json.Marshal(obj)
116	should.Nil(err)
117	should.Equal(``, str)
118}
119
120func Test_invalid_number(t *testing.T) {
121	type Message struct {
122		Number int `json:"number"`
123	}
124	obj := Message{}
125	decoder := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(bytes.NewBufferString(`{"number":"5"}`))
126	err := decoder.Decode(&obj)
127	invalidStr := err.Error()
128	result, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(invalidStr)
129	should := require.New(t)
130	should.Nil(err)
131	result2, err := json.Marshal(invalidStr)
132	should.Nil(err)
133	should.Equal(string(result2), string(result))
134}
135
136func Test_valid(t *testing.T) {
137	should := require.New(t)
138	should.True(jsoniter.Valid([]byte(`{}`)))
139	should.False(jsoniter.Valid([]byte(`{`)))
140}
141
142func Test_nil_pointer(t *testing.T) {
143	should := require.New(t)
144	data := []byte(`{"A":0}`)
145	type T struct {
146		X int
147	}
148	var obj *T
149	err := jsoniter.Unmarshal(data, obj)
150	should.NotNil(err)
151}
152
153func Test_func_pointer_type(t *testing.T) {
154	type TestObject2 struct {
155		F func()
156	}
157	type TestObject1 struct {
158		Obj *TestObject2
159	}
160	t.Run("encode null is valid", func(t *testing.T) {
161		should := require.New(t)
162		output, err := json.Marshal(TestObject1{})
163		should.Nil(err)
164		should.Equal(`{"Obj":null}`, string(output))
165		output, err = jsoniter.Marshal(TestObject1{})
166		should.Nil(err)
167		should.Equal(`{"Obj":null}`, string(output))
168	})
169	t.Run("encode not null is invalid", func(t *testing.T) {
170		should := require.New(t)
171		_, err := json.Marshal(TestObject1{Obj: &TestObject2{}})
172		should.NotNil(err)
173		_, err = jsoniter.Marshal(TestObject1{Obj: &TestObject2{}})
174		should.NotNil(err)
175	})
176	t.Run("decode null is valid", func(t *testing.T) {
177		should := require.New(t)
178		var obj TestObject1
179		should.Nil(json.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
180		should.Nil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
181	})
182	t.Run("decode not null is invalid", func(t *testing.T) {
183		should := require.New(t)
184		var obj TestObject1
185		should.NotNil(json.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
186		should.NotNil(jsoniter.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
187	})
188}
189
190func TestEOF(t *testing.T) {
191	var s string
192	err := jsoniter.ConfigCompatibleWithStandardLibrary.NewDecoder(&bytes.Buffer{}).Decode(&s)
193	assert.Equal(t, io.EOF, err)
194}
195
196func TestDecodeErrorType(t *testing.T) {
197	should := require.New(t)
198	var err error
199	should.Nil(jsoniter.Unmarshal([]byte("null"), &err))
200	should.NotNil(jsoniter.Unmarshal([]byte("123"), &err))
201}
202
203func Test_decode_slash(t *testing.T) {
204	should := require.New(t)
205	var obj interface{}
206	should.NotNil(json.Unmarshal([]byte("\\"), &obj))
207	should.NotNil(jsoniter.UnmarshalFromString("\\", &obj))
208}
209
210func Test_NilInput(t *testing.T) {
211	var jb []byte // nil
212	var out string
213	err := jsoniter.Unmarshal(jb, &out)
214	if err == nil {
215		t.Errorf("Expected error")
216	}
217}
218
219func Test_EmptyInput(t *testing.T) {
220	jb := []byte("")
221	var out string
222	err := jsoniter.Unmarshal(jb, &out)
223	if err == nil {
224		t.Errorf("Expected error")
225	}
226}
227
228type Foo struct {
229	A jsoniter.Any
230}
231
232func Test_nil_any(t *testing.T) {
233	should := require.New(t)
234	data, _ := jsoniter.Marshal(&Foo{})
235	should.Equal(`{"A":null}`, string(data))
236}
237