1
16
17 package ast
18
19 import (
20 `testing`
21 `strings`
22
23 `github.com/stretchr/testify/assert`
24 )
25
26 type Path = []interface{}
27
28 type testGetApi struct {
29 json string
30 path Path
31 }
32
33 type checkError func(error) bool
34
35 func isSyntaxError(err error) bool {
36 if err == nil {
37 return false
38 }
39 return strings.HasPrefix(err.Error(), `"Syntax error at index`)
40 }
41
42 func isEmptySource(err error) bool {
43 if err == nil {
44 return false
45 }
46 return strings.Contains(err.Error(), "no sources available")
47 }
48
49 func isErrNotExist(err error) bool {
50 return err == ErrNotExist
51 }
52
53 func isErrUnsupportType(err error) bool {
54 return err == ErrUnsupportType
55 }
56
57 func testSyntaxJson(t *testing.T, json string, path ...interface{}) {
58 search := NewSearcher(json)
59 _, err := search.GetByPath(path...)
60 assert.True(t, isSyntaxError(err))
61 }
62
63 func TestGetFromEmptyJson(t *testing.T) {
64 tests := []testGetApi {
65 { "", nil },
66 { "", Path{}},
67 { "", Path{""}},
68 { "", Path{0}},
69 { "", Path{"", ""}},
70 }
71 for _, test := range tests {
72 f := func(t *testing.T) {
73 search := NewSearcher(test.json)
74 _, err := search.GetByPath(test.path...)
75 assert.True(t, isEmptySource(err))
76 }
77 t.Run(test.json, f)
78 }
79 }
80
81 func TestGetFromSyntaxError(t *testing.T) {
82 tests := []testGetApi {
83 { " \r\n\f\t", Path{} },
84 { "123.", Path{} },
85 { "+124", Path{} },
86 { "-", Path{} },
87 { "-e123", Path{} },
88 { "-1.e123", Path{} },
89 { "-12e456.1", Path{} },
90 { "-12e.1", Path{} },
91 { "[", Path{} },
92 { "{", Path{} },
93 { "[}", Path{} },
94 { "{]", Path{} },
95 { "{,}", Path{} },
96 { "[,]", Path{} },
97 { "tru", Path{} },
98 { "fals", Path{} },
99 { "nul", Path{} },
100 { `{"a":"`, Path{"a"} },
101 { `{"`, Path{} },
102 { `"`, Path{} },
103 { `"\"`, Path{} },
104 { `"\\\"`, Path{} },
105 { `"hello`, Path{} },
106 { `{{}}`, Path{} },
107 { `{[]}`, Path{} },
108 { `{:,}`, Path{} },
109 { `{test:error}`, Path{} },
110 { `{":true}`, Path{} },
111 { `{"" false}`, Path{} },
112 { `{ "" : "false }`, Path{} },
113 { `{"":"",}`, Path{} },
114 { `{ " test : true}`, Path{} },
115 { `{ "test" : tru }`, Path{} },
116 { `{ "test" : true , }`, Path{} },
117 { `{ {"test" : true , } }`, Path{} },
118 { `{"test":1. }`, Path{} },
119 { `{"\\\""`, Path{} },
120 { `{"\\\"":`, Path{} },
121 { `{"\\\":",""}`, Path{} },
122 { `[{]`, Path{} },
123 { `[tru]`, Path{} },
124 { `[-1.]`, Path{} },
125 { `[[]`, Path{} },
126 { `[[],`, Path{} },
127 { `[ true , false , [ ]`, Path{} },
128 { `[true, false, [],`, Path{} },
129 { `[true, false, [],]`, Path{} },
130 { `{"key": [true, false, []], "key2": {{}}`, Path{} },
131 }
132
133 for _, test := range tests {
134 f := func(t *testing.T) {
135 testSyntaxJson(t, test.json, test.path...)
136 path := append(Path{"key"}, test.path...)
137 testSyntaxJson(t, `{"key":` + test.json, path...)
138 path = append(Path{""}, test.path...)
139 testSyntaxJson(t, `{"":` + test.json, path...)
140 path = append(Path{1}, test.path...)
141 testSyntaxJson(t, `["",` + test.json, path...)
142 }
143 t.Run(test.json, f)
144 }
145 }
146
147
148 func TestGetWithInvalidUndemandedField(t *testing.T) {
149 type Any = interface{}
150 tests := []struct {
151 json string
152 path Path
153 exp Any
154 } {
155 { "-0xyz", Path{}, Any(float64(-0))},
156 { "-12e4xyz", Path{}, Any(float64(-12e4))},
157 { "truex", Path{}, Any(true)},
158 { "false,", Path{}, Any(false)},
159 { `{"a":{,xxx},"b":true}`, Path{"b"}, Any(true)},
160 { `{"a":[,xxx],"b":true}`, Path{"b"}, Any(true)},
161 }
162
163 for _, test := range tests {
164 f := func(t *testing.T) {
165 search := NewSearcher(test.json)
166 node, err := search.GetByPath(test.path...)
167 assert.NoError(t, err)
168 v, err := node.Interface()
169 assert.NoError(t, err)
170 assert.Equal(t, v, test.exp)
171 }
172 t.Run(test.json, f)
173 }
174 }
175
176 func TestGet_InvalidPathType(t *testing.T) {
177 assert.Panics(t, assert.PanicTestFunc(func() {
178 data := `{"a":[{"b":true}]}`
179 s := NewSearcher(data)
180 s.GetByPath("a", true)
181
182 s = NewSearcher(data)
183 s.GetByPath("a", nil)
184
185 s = NewSearcher(data)
186 s.GetByPath("a", -1)
187 }))
188 }
189
View as plain text