Skip to content

Commit b1fc178

Browse files
committed
Added support for slice ranges in dotpaths
1 parent ea38c2f commit b1fc178

File tree

2 files changed

+60
-15
lines changed

2 files changed

+60
-15
lines changed

dotpath/dotpath.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ func findInMap(p []string, m map[string]interface{}) (interface{}, error) {
135135
func findInArray(p []string, a []interface{}) (interface{}, error) {
136136
if len(p) > 0 {
137137
if strings.Contains(p[0], ":") == true {
138-
//FIXME: Need to return array of remaining dot paths
139138
pts := strings.Split(p[0], ":")
140139
if len(pts) != 2 {
141140
return nil, fmt.Errorf("%q is an invalid range", p[0])
@@ -153,15 +152,14 @@ func findInArray(p []string, a []interface{}) (interface{}, error) {
153152
return nil, fmt.Errorf("error parsing start of range %q, %s", p[0], err)
154153
}
155154
if strings.TrimSpace(pts[1]) == "" {
156-
j = len(a) - 1
155+
j = len(a)
157156
} else {
158157
j, err = strconv.Atoi(pts[1])
159158
}
160159
if err != nil {
161160
return nil, fmt.Errorf("error parsing end of range %q, %s", p[0], err)
162161
}
163162
if len(p) > 1 {
164-
fmt.Printf("DEBUG rest of p: %+v, a -> %+v\n", p[1:], a[i:j])
165163
v := []interface{}{}
166164
for _, sVal := range a[i:j] {
167165
if d, err := find(p[1:], sVal); err != nil {
@@ -170,8 +168,7 @@ func findInArray(p []string, a []interface{}) (interface{}, error) {
170168
v = append(v, d)
171169
}
172170
}
173-
fmt.Printf("DEBUG v: %T -> %+v\n", v, v)
174-
return v, nil //fmt.Errorf("range with sub-paths not implemented")
171+
return v, nil
175172
}
176173
return a[i:j], nil
177174
}

dotpath/dotpath_test.go

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,18 @@ func TestEval(t *testing.T) {
268268
"last": "Zip"
269269
},
270270
"works": [
271-
{"title":"One"},
272-
{"title": "two"},
273-
{"title": "three"}
274-
],
275-
"dates": [
276-
{ "year": 1992, "month": 10, "day": 23 },
277-
{ "year": 2016, "month": 2, "day": 21 }
271+
{
272+
"title":"One",
273+
"pubdate": { "year": 1992, "month": 10, "day": 23 }
274+
},
275+
{
276+
"title": "Two",
277+
"pubdate": { "year": 2017, "month": 2, "day": 21 }
278+
},
279+
{
280+
"title": "Three",
281+
"pubdate": { "year": 2003, "month": 12, "day": 1 }
282+
}
278283
]
279284
}`)
280285

@@ -413,19 +418,62 @@ func TestEval(t *testing.T) {
413418
}
414419
switch blob.(type) {
415420
case []interface{}:
416-
t.Errorf("DEBUG, %T -> %+v", blob, blob)
421+
obj := blob.([]interface{})
417422
for i, s := range []string{"One", "Two", "Three"} {
418-
if blob.([]interface{})[i].(string) != s {
419-
t.Errorf("Expected %q, got %T -> %+v", s, blob, blob)
423+
if i < len(obj) && obj[i].(string) != s {
424+
t.Errorf("Expected %q, got %T -> %+v", s, obj, obj)
420425
t.FailNow()
426+
} else if i >= len(obj) {
427+
t.Errorf("Missing array value at %d -> %+v", i, obj)
428+
}
429+
}
430+
default:
431+
t.Errorf("Expected string, %T", blob)
432+
t.FailNow()
433+
}
434+
435+
// Test return a sub-slice
436+
p = ".works[1:3].pubdate"
437+
blob, err = Eval(p, data)
438+
if err != nil {
439+
t.Errorf("Eval() returned an error, %s", err)
440+
t.FailNow()
441+
}
442+
switch blob.(type) {
443+
case []interface{}:
444+
obj := blob.([]interface{})
445+
if len(obj) != 2 {
446+
t.Errorf("Expected two elements in array, got %T -> %+v", obj, obj)
447+
t.FailNow()
448+
}
449+
pubdate := obj[0].(map[string]interface{})
450+
if day, ok := pubdate["day"]; ok == true {
451+
if dy, err := day.(json.Number).Int64(); err == nil && dy != int64(21) {
452+
t.Errorf("Expected day == 21, got %d", day)
453+
} else if err != nil {
454+
t.Errorf("Error getting a day for %T %+v, %s", obj, obj, err)
421455
}
456+
} else {
457+
t.Errorf("Expected a day, day missing, %T %+v", obj, obj)
458+
}
459+
pubdate = obj[1].(map[string]interface{})
460+
if year, ok := pubdate["year"]; ok == true {
461+
if yr, err := year.(json.Number).Int64(); err == nil && yr != int64(2003) {
462+
t.Errorf("Expected year == 2003, got %d", year)
463+
} else if err != nil {
464+
t.Errorf("Error getting a year for %T %+v, %s", obj, obj, err)
465+
}
466+
} else {
467+
t.Errorf("Expected a year, year missing, %T %+v", obj, obj)
422468
}
423469
default:
424470
t.Errorf("Expected string, %T", blob)
425471
t.FailNow()
426472
}
473+
427474
} else {
428475
t.Errorf("Expected data to have %q, %T -> %+v", p, data, data)
429476
t.FailNow()
430477
}
478+
431479
}

0 commit comments

Comments
 (0)