1 package jsonpath
2
3 import (
4 "bytes"
5 "fmt"
6 "reflect"
7 "testing"
8 )
9
10 var decoderSkipTests = []struct {
11 in string
12 path []interface{}
13 match bool
14 err error
15 out interface{}
16 }{
17 {in: `{}`, path: []interface{}{"a", "b2"}, match: false, err: nil},
18 {in: `{"a":{"b":{"c":14}}}`, path: []interface{}{"a"}, match: true, out: map[string]interface{}{"b": map[string]interface{}{"c": float64(14)}}, err: nil},
19 {in: `{"a":{"b":{"c":14}}}`, path: []interface{}{"a", "b"}, match: true, out: map[string]interface{}{"c": float64(14)}, err: nil},
20 {in: `{"a":{"b":{"c":14}}}`, path: []interface{}{"a", "b", "c"}, match: true, out: float64(14), err: nil},
21 {in: `{"a":{"d":{"b":{"c":3}}, "b":{"c":14}}}`, path: []interface{}{"a", "b", "c"}, match: true, out: float64(14), err: nil},
22 {in: `{"a":{"b":{"c":14},"b2":3}}`, path: []interface{}{"a", "b2"}, match: true, out: float64(3), err: nil},
23
24 {in: `[]`, path: []interface{}{2}, match: false, err: nil},
25 {in: `[0,1]`, path: []interface{}{0}, match: true, out: float64(0), err: nil},
26 {in: `[0,1,2]`, path: []interface{}{2}, match: true, out: float64(2), err: nil},
27 {in: `[0,1 , 2]`, path: []interface{}{2}, match: true, out: float64(2), err: nil},
28 {in: `[0,{"b":1},2]`, path: []interface{}{1}, match: true, out: map[string]interface{}{"b": float64(1)}, err: nil},
29 {in: `[1,{"b":1},2]`, path: []interface{}{2}, match: true, out: float64(2), err: nil},
30 {in: `[1,{"b":[1]},2]`, path: []interface{}{2}, match: true, out: float64(2), err: nil},
31 {in: `[1,[{"b":[1]},3],2]`, path: []interface{}{2}, match: true, out: float64(2), err: nil},
32
33 {in: `[1,[{"b":[1]},3],4]`, path: []interface{}{1, 1}, match: true, out: float64(3), err: nil},
34 {in: `[1,[{"b":[1]},3],2]`, path: []interface{}{1, 0, "b", 0}, match: true, out: float64(1), err: nil},
35 {in: `[1,[{"b":[1]},3],5]`, path: []interface{}{2}, match: true, out: float64(5), err: nil},
36 {in: `{"b":[{"a":0},{"a":1}]}`, path: []interface{}{"b", 0, "a"}, match: true, out: float64(0), err: nil},
37 {in: `{"b":[{"a":0},{"a":1}]}`, path: []interface{}{"b", 1, "a"}, match: true, out: float64(1), err: nil},
38 {in: `{"a":"b","b":"z","z":"s"}`, path: []interface{}{"b"}, match: true, out: "z", err: nil},
39 {in: `{"a":"b","b":"z","l":0,"z":"s"}`, path: []interface{}{"z"}, match: true, out: "s", err: nil},
40 }
41
42 func TestDecoderSeekTo(t *testing.T) {
43 var testDesc string
44 var v interface{}
45 var match bool
46 var err error
47
48 for ti, tst := range decoderSkipTests {
49
50 w := NewDecoder(bytes.NewBuffer([]byte(tst.in)))
51 testDesc = fmt.Sprintf("#%v '%s'", ti, tst.in)
52
53 match, err = w.SeekTo(tst.path...)
54 if match != tst.match {
55 t.Errorf("#%v expected match=%v was match=%v : %v", ti, tst.match, match, testDesc)
56 }
57 if !reflect.DeepEqual(err, tst.err) {
58 t.Errorf("#%v unexpected error: '%v' expecting '%v' : %v", ti, err, tst.err, testDesc)
59 }
60
61 if match {
62 if err = w.Decode(&v); err != nil {
63 t.Errorf("#%v decode: error: '%v' : %v", ti, err, testDesc)
64 }
65 if !reflect.DeepEqual(v, tst.out) {
66 t.Errorf("#%v decode: expected %#v, was %#v : %v", ti, tst.out, v, testDesc)
67 }
68 }
69 }
70 }
71
72 func TestDecoderMoveMultiple(t *testing.T) {
73
74 j := []byte(`
75 {
76 "foo": 1,
77 "bar": 2,
78 "test": "Hello, world!",
79 "baz": 123.1,
80 "array": [
81 {"foo": 1},
82 {"bar": 2},
83 {"baz": 3}
84 ],
85 "subobj": {
86 "foo": 1,
87 "subarray": [1,2,3],
88 "subsubobj": {
89 "bar": 2,
90 "baz": 3,
91 "array": ["hello", "world"]
92 }
93 },
94 "bool": true
95 }`)
96
97 tests := [][]struct {
98 path []interface{}
99 out interface{}
100 match bool
101 }{
102 {
103 {path: []interface{}{"foo"}, match: true, out: float64(1)},
104 {path: []interface{}{"bar"}, match: true, out: float64(2)},
105 {path: []interface{}{"test"}, match: true, out: "Hello, world!"},
106 {path: []interface{}{"baz"}, match: true, out: float64(123.1)},
107 {path: []interface{}{"array", 0, "foo"}, match: true, out: float64(1)},
108 {path: []interface{}{"array", 1, "bar"}, match: true, out: float64(2)},
109 {path: []interface{}{"array", 2, "baz"}, match: true, out: float64(3)},
110 {path: []interface{}{"subobj", "foo"}, match: true, out: float64(1)},
111 {path: []interface{}{"subobj", "subarray", 0}, match: true, out: float64(1)},
112 {path: []interface{}{"subobj", "subarray", 1}, match: true, out: float64(2)},
113 {path: []interface{}{"subobj", "subarray", 2}, match: true, out: float64(3)},
114 {path: []interface{}{"subobj", "subsubobj", "bar"}, match: true, out: float64(2)},
115 {path: []interface{}{"subobj", "subsubobj", "baz"}, match: true, out: float64(3)},
116 {path: []interface{}{"subobj", "subsubobj", "array", 0}, match: true, out: "hello"},
117 {path: []interface{}{"subobj", "subsubobj", "array", 1}, match: true, out: "world"},
118 {path: []interface{}{"bool"}, match: true, out: true},
119 },
120 {
121 {path: []interface{}{"subobj", "subsubobj", "array", 0}, match: true, out: "hello"},
122 {path: []interface{}{"bool"}, match: true, out: true},
123 },
124 {
125 {path: []interface{}{"array"}, match: true, out: []interface{}{map[string]interface{}{"foo": float64(1)}, map[string]interface{}{"bar": float64(2)}, map[string]interface{}{"baz": float64(3)}}},
126 {path: []interface{}{"subobj", "subsubobj"}, match: true, out: map[string]interface{}{"bar": float64(2), "baz": float64(3), "array": []interface{}{"hello", "world"}}},
127 {path: []interface{}{"bool"}, match: true, out: true},
128 },
129 {
130 {path: []interface{}{"foo"}, match: true, out: float64(1)},
131 {path: []interface{}{"test"}, match: true, out: "Hello, world!"},
132 {path: []interface{}{"array", 1, "bar"}, match: true, out: float64(2)},
133 {path: []interface{}{"subobj", "subarray", 1}, match: true, out: float64(2)},
134 {path: []interface{}{"subobj", "subarray", 2}, match: true, out: float64(3)},
135 {path: []interface{}{"subobj", "subsubobj", "array", 1}, match: true, out: "world"},
136 },
137 }
138
139 for _, tst := range tests {
140
141 w := NewDecoder(bytes.NewBuffer(j))
142
143 var err error
144 var v interface{}
145 var m bool
146
147 for i, step := range tst {
148
149 m, err = w.SeekTo(step.path...)
150 if m != step.match {
151 t.Errorf("@%v expected match=%v, but was match=%v", i, step.match, m)
152 }
153 if err != nil {
154 t.Errorf("unexpected error: %v", err)
155 }
156 err = w.Decode(&v)
157 if err != nil {
158 t.Errorf("unexpected error: %v", err)
159 }
160 if !reflect.DeepEqual(v, step.out) {
161 t.Errorf("expected %v but was %v", step.out, v)
162 }
163 }
164 }
165
166 }
167
View as plain text