OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / pelletier / go-toml / query / parser_test.go
1 package query
2
3 import (
4         "fmt"
5         "github.com/pelletier/go-toml"
6         "io/ioutil"
7         "sort"
8         "strings"
9         "testing"
10         "time"
11 )
12
13 type queryTestNode struct {
14         value    interface{}
15         position toml.Position
16 }
17
18 func valueString(root interface{}) string {
19         result := "" //fmt.Sprintf("%T:", root)
20         switch node := root.(type) {
21         case *Result:
22                 items := []string{}
23                 for i, v := range node.Values() {
24                         items = append(items, fmt.Sprintf("%s:%s",
25                                 node.Positions()[i].String(), valueString(v)))
26                 }
27                 sort.Strings(items)
28                 result = "[" + strings.Join(items, ", ") + "]"
29         case queryTestNode:
30                 result = fmt.Sprintf("%s:%s",
31                         node.position.String(), valueString(node.value))
32         case []interface{}:
33                 items := []string{}
34                 for _, v := range node {
35                         items = append(items, valueString(v))
36                 }
37                 sort.Strings(items)
38                 result = "[" + strings.Join(items, ", ") + "]"
39         case *toml.Tree:
40                 // workaround for unreliable map key ordering
41                 items := []string{}
42                 for _, k := range node.Keys() {
43                         v := node.GetPath([]string{k})
44                         items = append(items, k+":"+valueString(v))
45                 }
46                 sort.Strings(items)
47                 result = "{" + strings.Join(items, ", ") + "}"
48         case map[string]interface{}:
49                 // workaround for unreliable map key ordering
50                 items := []string{}
51                 for k, v := range node {
52                         items = append(items, k+":"+valueString(v))
53                 }
54                 sort.Strings(items)
55                 result = "{" + strings.Join(items, ", ") + "}"
56         case int64:
57                 result += fmt.Sprintf("%d", node)
58         case string:
59                 result += "'" + node + "'"
60         case float64:
61                 result += fmt.Sprintf("%f", node)
62         case bool:
63                 result += fmt.Sprintf("%t", node)
64         case time.Time:
65                 result += fmt.Sprintf("'%v'", node)
66         }
67         return result
68 }
69
70 func assertValue(t *testing.T, result, ref interface{}) {
71         pathStr := valueString(result)
72         refStr := valueString(ref)
73         if pathStr != refStr {
74                 t.Errorf("values do not match")
75                 t.Log("test:", pathStr)
76                 t.Log("ref: ", refStr)
77         }
78 }
79
80 func assertQueryPositions(t *testing.T, tomlDoc string, query string, ref []interface{}) {
81         tree, err := toml.Load(tomlDoc)
82         if err != nil {
83                 t.Errorf("Non-nil toml parse error: %v", err)
84                 return
85         }
86         q, err := Compile(query)
87         if err != nil {
88                 t.Error(err)
89                 return
90         }
91         results := q.Execute(tree)
92         assertValue(t, results, ref)
93 }
94
95 func TestQueryRoot(t *testing.T) {
96         assertQueryPositions(t,
97                 "a = 42",
98                 "$",
99                 []interface{}{
100                         queryTestNode{
101                                 map[string]interface{}{
102                                         "a": int64(42),
103                                 }, toml.Position{1, 1},
104                         },
105                 })
106 }
107
108 func TestQueryKey(t *testing.T) {
109         assertQueryPositions(t,
110                 "[foo]\na = 42",
111                 "$.foo.a",
112                 []interface{}{
113                         queryTestNode{
114                                 int64(42), toml.Position{2, 1},
115                         },
116                 })
117 }
118
119 func TestQueryKeyString(t *testing.T) {
120         assertQueryPositions(t,
121                 "[foo]\na = 42",
122                 "$.foo['a']",
123                 []interface{}{
124                         queryTestNode{
125                                 int64(42), toml.Position{2, 1},
126                         },
127                 })
128 }
129
130 func TestQueryIndex(t *testing.T) {
131         assertQueryPositions(t,
132                 "[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
133                 "$.foo.a[5]",
134                 []interface{}{
135                         queryTestNode{
136                                 int64(6), toml.Position{2, 1},
137                         },
138                 })
139 }
140
141 func TestQuerySliceRange(t *testing.T) {
142         assertQueryPositions(t,
143                 "[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
144                 "$.foo.a[0:5]",
145                 []interface{}{
146                         queryTestNode{
147                                 int64(1), toml.Position{2, 1},
148                         },
149                         queryTestNode{
150                                 int64(2), toml.Position{2, 1},
151                         },
152                         queryTestNode{
153                                 int64(3), toml.Position{2, 1},
154                         },
155                         queryTestNode{
156                                 int64(4), toml.Position{2, 1},
157                         },
158                         queryTestNode{
159                                 int64(5), toml.Position{2, 1},
160                         },
161                 })
162 }
163
164 func TestQuerySliceStep(t *testing.T) {
165         assertQueryPositions(t,
166                 "[foo]\na = [1,2,3,4,5,6,7,8,9,0]",
167                 "$.foo.a[0:5:2]",
168                 []interface{}{
169                         queryTestNode{
170                                 int64(1), toml.Position{2, 1},
171                         },
172                         queryTestNode{
173                                 int64(3), toml.Position{2, 1},
174                         },
175                         queryTestNode{
176                                 int64(5), toml.Position{2, 1},
177                         },
178                 })
179 }
180
181 func TestQueryAny(t *testing.T) {
182         assertQueryPositions(t,
183                 "[foo.bar]\na=1\nb=2\n[foo.baz]\na=3\nb=4",
184                 "$.foo.*",
185                 []interface{}{
186                         queryTestNode{
187                                 map[string]interface{}{
188                                         "a": int64(1),
189                                         "b": int64(2),
190                                 }, toml.Position{1, 1},
191                         },
192                         queryTestNode{
193                                 map[string]interface{}{
194                                         "a": int64(3),
195                                         "b": int64(4),
196                                 }, toml.Position{4, 1},
197                         },
198                 })
199 }
200 func TestQueryUnionSimple(t *testing.T) {
201         assertQueryPositions(t,
202                 "[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
203                 "$.*[bar,foo]",
204                 []interface{}{
205                         queryTestNode{
206                                 map[string]interface{}{
207                                         "a": int64(1),
208                                         "b": int64(2),
209                                 }, toml.Position{1, 1},
210                         },
211                         queryTestNode{
212                                 map[string]interface{}{
213                                         "a": int64(3),
214                                         "b": int64(4),
215                                 }, toml.Position{4, 1},
216                         },
217                         queryTestNode{
218                                 map[string]interface{}{
219                                         "a": int64(5),
220                                         "b": int64(6),
221                                 }, toml.Position{7, 1},
222                         },
223                 })
224 }
225
226 func TestQueryRecursionAll(t *testing.T) {
227         assertQueryPositions(t,
228                 "[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
229                 "$..*",
230                 []interface{}{
231                         queryTestNode{
232                                 map[string]interface{}{
233                                         "foo": map[string]interface{}{
234                                                 "bar": map[string]interface{}{
235                                                         "a": int64(1),
236                                                         "b": int64(2),
237                                                 },
238                                         },
239                                         "baz": map[string]interface{}{
240                                                 "foo": map[string]interface{}{
241                                                         "a": int64(3),
242                                                         "b": int64(4),
243                                                 },
244                                         },
245                                         "gorf": map[string]interface{}{
246                                                 "foo": map[string]interface{}{
247                                                         "a": int64(5),
248                                                         "b": int64(6),
249                                                 },
250                                         },
251                                 }, toml.Position{1, 1},
252                         },
253                         queryTestNode{
254                                 map[string]interface{}{
255                                         "bar": map[string]interface{}{
256                                                 "a": int64(1),
257                                                 "b": int64(2),
258                                         },
259                                 }, toml.Position{1, 1},
260                         },
261                         queryTestNode{
262                                 map[string]interface{}{
263                                         "a": int64(1),
264                                         "b": int64(2),
265                                 }, toml.Position{1, 1},
266                         },
267                         queryTestNode{
268                                 int64(1), toml.Position{2, 1},
269                         },
270                         queryTestNode{
271                                 int64(2), toml.Position{3, 1},
272                         },
273                         queryTestNode{
274                                 map[string]interface{}{
275                                         "foo": map[string]interface{}{
276                                                 "a": int64(3),
277                                                 "b": int64(4),
278                                         },
279                                 }, toml.Position{4, 1},
280                         },
281                         queryTestNode{
282                                 map[string]interface{}{
283                                         "a": int64(3),
284                                         "b": int64(4),
285                                 }, toml.Position{4, 1},
286                         },
287                         queryTestNode{
288                                 int64(3), toml.Position{5, 1},
289                         },
290                         queryTestNode{
291                                 int64(4), toml.Position{6, 1},
292                         },
293                         queryTestNode{
294                                 map[string]interface{}{
295                                         "foo": map[string]interface{}{
296                                                 "a": int64(5),
297                                                 "b": int64(6),
298                                         },
299                                 }, toml.Position{7, 1},
300                         },
301                         queryTestNode{
302                                 map[string]interface{}{
303                                         "a": int64(5),
304                                         "b": int64(6),
305                                 }, toml.Position{7, 1},
306                         },
307                         queryTestNode{
308                                 int64(5), toml.Position{8, 1},
309                         },
310                         queryTestNode{
311                                 int64(6), toml.Position{9, 1},
312                         },
313                 })
314 }
315
316 func TestQueryRecursionUnionSimple(t *testing.T) {
317         assertQueryPositions(t,
318                 "[foo.bar]\na=1\nb=2\n[baz.foo]\na=3\nb=4\n[gorf.foo]\na=5\nb=6",
319                 "$..['foo','bar']",
320                 []interface{}{
321                         queryTestNode{
322                                 map[string]interface{}{
323                                         "bar": map[string]interface{}{
324                                                 "a": int64(1),
325                                                 "b": int64(2),
326                                         },
327                                 }, toml.Position{1, 1},
328                         },
329                         queryTestNode{
330                                 map[string]interface{}{
331                                         "a": int64(3),
332                                         "b": int64(4),
333                                 }, toml.Position{4, 1},
334                         },
335                         queryTestNode{
336                                 map[string]interface{}{
337                                         "a": int64(1),
338                                         "b": int64(2),
339                                 }, toml.Position{1, 1},
340                         },
341                         queryTestNode{
342                                 map[string]interface{}{
343                                         "a": int64(5),
344                                         "b": int64(6),
345                                 }, toml.Position{7, 1},
346                         },
347                 })
348 }
349
350 func TestQueryFilterFn(t *testing.T) {
351         buff, err := ioutil.ReadFile("../example.toml")
352         if err != nil {
353                 t.Error(err)
354                 return
355         }
356
357         assertQueryPositions(t, string(buff),
358                 "$..[?(int)]",
359                 []interface{}{
360                         queryTestNode{
361                                 int64(8001), toml.Position{13, 1},
362                         },
363                         queryTestNode{
364                                 int64(8001), toml.Position{13, 1},
365                         },
366                         queryTestNode{
367                                 int64(8002), toml.Position{13, 1},
368                         },
369                         queryTestNode{
370                                 int64(5000), toml.Position{14, 1},
371                         },
372                 })
373
374         assertQueryPositions(t, string(buff),
375                 "$..[?(string)]",
376                 []interface{}{
377                         queryTestNode{
378                                 "TOML Example", toml.Position{3, 1},
379                         },
380                         queryTestNode{
381                                 "Tom Preston-Werner", toml.Position{6, 1},
382                         },
383                         queryTestNode{
384                                 "GitHub", toml.Position{7, 1},
385                         },
386                         queryTestNode{
387                                 "GitHub Cofounder & CEO\nLikes tater tots and beer.",
388                                 toml.Position{8, 1},
389                         },
390                         queryTestNode{
391                                 "192.168.1.1", toml.Position{12, 1},
392                         },
393                         queryTestNode{
394                                 "10.0.0.1", toml.Position{21, 3},
395                         },
396                         queryTestNode{
397                                 "eqdc10", toml.Position{22, 3},
398                         },
399                         queryTestNode{
400                                 "10.0.0.2", toml.Position{25, 3},
401                         },
402                         queryTestNode{
403                                 "eqdc10", toml.Position{26, 3},
404                         },
405                 })
406
407         assertQueryPositions(t, string(buff),
408                 "$..[?(float)]",
409                 []interface{}{
410                 // no float values in document
411                 })
412
413         tv, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
414         assertQueryPositions(t, string(buff),
415                 "$..[?(tree)]",
416                 []interface{}{
417                         queryTestNode{
418                                 map[string]interface{}{
419                                         "name":         "Tom Preston-Werner",
420                                         "organization": "GitHub",
421                                         "bio":          "GitHub Cofounder & CEO\nLikes tater tots and beer.",
422                                         "dob":          tv,
423                                 }, toml.Position{5, 1},
424                         },
425                         queryTestNode{
426                                 map[string]interface{}{
427                                         "server":         "192.168.1.1",
428                                         "ports":          []interface{}{int64(8001), int64(8001), int64(8002)},
429                                         "connection_max": int64(5000),
430                                         "enabled":        true,
431                                 }, toml.Position{11, 1},
432                         },
433                         queryTestNode{
434                                 map[string]interface{}{
435                                         "alpha": map[string]interface{}{
436                                                 "ip": "10.0.0.1",
437                                                 "dc": "eqdc10",
438                                         },
439                                         "beta": map[string]interface{}{
440                                                 "ip": "10.0.0.2",
441                                                 "dc": "eqdc10",
442                                         },
443                                 }, toml.Position{17, 1},
444                         },
445                         queryTestNode{
446                                 map[string]interface{}{
447                                         "ip": "10.0.0.1",
448                                         "dc": "eqdc10",
449                                 }, toml.Position{20, 3},
450                         },
451                         queryTestNode{
452                                 map[string]interface{}{
453                                         "ip": "10.0.0.2",
454                                         "dc": "eqdc10",
455                                 }, toml.Position{24, 3},
456                         },
457                         queryTestNode{
458                                 map[string]interface{}{
459                                         "data": []interface{}{
460                                                 []interface{}{"gamma", "delta"},
461                                                 []interface{}{int64(1), int64(2)},
462                                         },
463                                 }, toml.Position{28, 1},
464                         },
465                 })
466
467         assertQueryPositions(t, string(buff),
468                 "$..[?(time)]",
469                 []interface{}{
470                         queryTestNode{
471                                 tv, toml.Position{9, 1},
472                         },
473                 })
474
475         assertQueryPositions(t, string(buff),
476                 "$..[?(bool)]",
477                 []interface{}{
478                         queryTestNode{
479                                 true, toml.Position{15, 1},
480                         },
481                 })
482 }