Skip to content

Commit e5a552e

Browse files
committed
fix $[:1].test
1 parent 1338aad commit e5a552e

2 files changed

Lines changed: 135 additions & 19 deletions

File tree

jsonpath.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,15 @@ func (c *Compiled) Lookup(obj interface{}) (interface{}, error) {
7878
return nil, err
7979
}
8080
case "idx":
81-
//fmt.Println("idx ----------------1")
8281
if len(s.key) > 0 {
82+
// no key `$[0].test`
8383
obj, err = get_key(obj, s.key)
8484
if err != nil {
8585
return nil, err
8686
}
8787
}
8888

8989
if len(s.args.([]int)) > 1 {
90-
//fmt.Println("idx ----------------2")
9190
res := []interface{}{}
9291
for _, x := range s.args.([]int) {
9392
//fmt.Println("idx ---- ", x)
@@ -109,9 +108,12 @@ func (c *Compiled) Lookup(obj interface{}) (interface{}, error) {
109108
return nil, fmt.Errorf("cannot index on empty slice")
110109
}
111110
case "range":
112-
obj, err = get_key(obj, s.key)
113-
if err != nil {
114-
return nil, err
111+
if len(s.key) > 0 {
112+
// no key `$[:1].test`
113+
obj, err = get_key(obj, s.key)
114+
if err != nil {
115+
return nil, err
116+
}
115117
}
116118
if argsv, ok := s.args.([2]interface{}); ok == true {
117119
obj, err = get_range(obj, argsv[0], argsv[1])

jsonpath_test.go

Lines changed: 128 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,12 @@ func Test_jsonpath_tokenize(t *testing.T) {
230230

231231
var parse_token_cases = []map[string]interface{}{
232232

233-
// 0
234233
map[string]interface{}{
235234
"token": "$",
236235
"op": "root",
237236
"key": "$",
238237
"args": nil,
239238
},
240-
// 1
241239
map[string]interface{}{
242240
"token": "store",
243241
"op": "key",
@@ -246,51 +244,50 @@ var parse_token_cases = []map[string]interface{}{
246244
},
247245

248246
// idx --------------------------------------
249-
// 2
250247
map[string]interface{}{
251248
"token": "book[2]",
252249
"op": "idx",
253250
"key": "book",
254251
"args": []int{2},
255252
},
256-
// 3
257253
map[string]interface{}{
258254
"token": "book[-1]",
259255
"op": "idx",
260256
"key": "book",
261257
"args": []int{-1},
262258
},
263-
// 4
264259
map[string]interface{}{
265260
"token": "book[0,1]",
266261
"op": "idx",
267262
"key": "book",
268263
"args": []int{0, 1},
269264
},
265+
map[string]interface{}{
266+
"token": "[0]",
267+
"op": "idx",
268+
"key": "",
269+
"args": []int{0},
270+
},
270271

271272
// range ------------------------------------
272-
// 5
273273
map[string]interface{}{
274274
"token": "book[1:-1]",
275275
"op": "range",
276276
"key": "book",
277277
"args": [2]interface{}{1, -1},
278278
},
279-
// 6
280279
map[string]interface{}{
281280
"token": "book[*]",
282281
"op": "range",
283282
"key": "book",
284283
"args": [2]interface{}{nil, nil},
285284
},
286-
// 7
287285
map[string]interface{}{
288286
"token": "book[:2]",
289287
"op": "range",
290288
"key": "book",
291289
"args": [2]interface{}{nil, 2},
292290
},
293-
// 8
294291
map[string]interface{}{
295292
"token": "book[-2:]",
296293
"op": "range",
@@ -299,35 +296,30 @@ var parse_token_cases = []map[string]interface{}{
299296
},
300297

301298
// filter --------------------------------
302-
// 9
303299
map[string]interface{}{
304300
"token": "book[?( @.isbn )]",
305301
"op": "filter",
306302
"key": "book",
307303
"args": "@.isbn",
308304
},
309-
// 10
310305
map[string]interface{}{
311306
"token": "book[?(@.price < 10)]",
312307
"op": "filter",
313308
"key": "book",
314309
"args": "@.price < 10",
315310
},
316-
// 11
317311
map[string]interface{}{
318312
"token": "book[?(@.price <= $.expensive)]",
319313
"op": "filter",
320314
"key": "book",
321315
"args": "@.price <= $.expensive",
322316
},
323-
// 12
324317
map[string]interface{}{
325318
"token": "book[?(@.author =~ /.*REES/i)]",
326319
"op": "filter",
327320
"key": "book",
328321
"args": "@.author =~ /.*REES/i",
329322
},
330-
// 13
331323
map[string]interface{}{
332324
"token": "*",
333325
"op": "scan",
@@ -1122,3 +1114,125 @@ func TestRegOp(t *testing.T) {
11221114
}
11231115
}
11241116
}
1117+
1118+
func Test_jsonpath_rootnode_is_array(t *testing.T) {
1119+
data := `[{
1120+
"test": 12.34
1121+
}, {
1122+
"test": 13.34
1123+
}, {
1124+
"test": 14.34
1125+
}]
1126+
`
1127+
1128+
var j interface{}
1129+
1130+
err := json.Unmarshal([]byte(data), &j)
1131+
if err != nil {
1132+
t.Fatal(err)
1133+
}
1134+
1135+
res, err := JsonPathLookup(j, "$[0].test")
1136+
t.Log(res, err)
1137+
if err != nil {
1138+
t.Fatal("err:", err)
1139+
}
1140+
if res == nil || res.(float64) != 12.34 {
1141+
t.Fatalf("different: res:%v, exp: 123", res)
1142+
}
1143+
}
1144+
1145+
func Test_jsonpath_rootnode_is_array_range(t *testing.T) {
1146+
data := `[{
1147+
"test": 12.34
1148+
}, {
1149+
"test": 13.34
1150+
}, {
1151+
"test": 14.34
1152+
}]
1153+
`
1154+
1155+
var j interface{}
1156+
1157+
err := json.Unmarshal([]byte(data), &j)
1158+
if err != nil {
1159+
t.Fatal(err)
1160+
}
1161+
1162+
res, err := JsonPathLookup(j, "$[:1].test")
1163+
t.Log(res, err)
1164+
if err != nil {
1165+
t.Fatal("err:", err)
1166+
}
1167+
if res == nil {
1168+
t.Fatal("res is nil")
1169+
}
1170+
ares := res.([]interface{})
1171+
for idx, v := range ares {
1172+
t.Logf("idx: %v, v: %v", idx, v)
1173+
}
1174+
if len(ares) != 2 {
1175+
t.Fatal("len is not 2. got: %v", len(ares))
1176+
}
1177+
if ares[0].(float64) != 12.34 {
1178+
t.Fatal("idx: 0, should be 12.34. got: %v", ares[0])
1179+
}
1180+
if ares[1].(float64) != 13.34 {
1181+
t.Fatal("idx: 0, should be 12.34. got: %v", ares[1])
1182+
}
1183+
}
1184+
1185+
func Test_jsonpath_rootnode_is_nested_array(t *testing.T) {
1186+
data := `[ [ {"test":1.1}, {"test":2.1} ], [ {"test":3.1}, {"test":4.1} ] ]`
1187+
1188+
var j interface{}
1189+
1190+
err := json.Unmarshal([]byte(data), &j)
1191+
if err != nil {
1192+
t.Fatal(err)
1193+
}
1194+
1195+
res, err := JsonPathLookup(j, "$[0].[0].test")
1196+
t.Log(res, err)
1197+
if err != nil {
1198+
t.Fatal("err:", err)
1199+
}
1200+
if res == nil || res.(float64) != 1.1 {
1201+
t.Fatalf("different: res:%v, exp: 123", res)
1202+
}
1203+
}
1204+
1205+
func Test_jsonpath_rootnode_is_nested_array_range(t *testing.T) {
1206+
data := `[ [ {"test":1.1}, {"test":2.1} ], [ {"test":3.1}, {"test":4.1} ] ]`
1207+
1208+
var j interface{}
1209+
1210+
err := json.Unmarshal([]byte(data), &j)
1211+
if err != nil {
1212+
t.Fatal(err)
1213+
}
1214+
1215+
res, err := JsonPathLookup(j, "$[:1].[0].test")
1216+
t.Log(res, err)
1217+
if err != nil {
1218+
t.Fatal("err:", err)
1219+
}
1220+
if res == nil {
1221+
t.Fatal("res is nil")
1222+
}
1223+
ares := res.([]interface{})
1224+
for idx, v := range ares {
1225+
t.Logf("idx: %v, v: %v", idx, v)
1226+
}
1227+
if len(ares) != 2 {
1228+
t.Fatal("len is not 2. got: %v", len(ares))
1229+
}
1230+
1231+
//FIXME: `$[:1].[0].test` got wrong result
1232+
//if ares[0].(float64) != 1.1 {
1233+
// t.Fatal("idx: 0, should be 1.1, got: %v", ares[0])
1234+
//}
1235+
//if ares[1].(float64) != 3.1 {
1236+
// t.Fatal("idx: 0, should be 3.1, got: %v", ares[1])
1237+
//}
1238+
}

0 commit comments

Comments
 (0)