enable string indexing/slicing and new selector tests
This commit is contained in:
@@ -229,17 +229,17 @@ func resolve(sel Selector, subject ipld.Node, at []string) (ipld.Node, error) {
|
|||||||
}
|
}
|
||||||
cur, _ = cur.LookupByIndex(int64(idx))
|
cur, _ = cur.LookupByIndex(int64(idx))
|
||||||
|
|
||||||
// TODO: cleanup if confirmed that slicing/indexing on string is not legal
|
case datamodel.Kind_String:
|
||||||
// case datamodel.Kind_String:
|
str, _ := cur.AsString()
|
||||||
// str, _ := cur.AsString()
|
runes := []rune(str)
|
||||||
// if idx < 0 {
|
if idx < 0 {
|
||||||
// idx = len(str) + idx
|
idx = len(runes) + idx
|
||||||
// }
|
}
|
||||||
// if idx < 0 || idx >= len(str) {
|
if idx < 0 || idx >= len(runes) {
|
||||||
// err := newResolutionError(fmt.Sprintf("index out of bounds: %d", seg.Index()), at)
|
err := newResolutionError(fmt.Sprintf("index out of bounds: %d", seg.Index()), at)
|
||||||
// return nil, errIfNotOptional(seg, err)
|
return nil, errIfNotOptional(seg, err)
|
||||||
// }
|
}
|
||||||
// cur = basicnode.NewString(string(str[idx]))
|
cur = basicnode.NewString(string(runes[idx]))
|
||||||
|
|
||||||
case datamodel.Kind_Bytes:
|
case datamodel.Kind_Bytes:
|
||||||
b, _ := cur.AsBytes()
|
b, _ := cur.AsBytes()
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/ipld/go-ipld-prime"
|
"github.com/ipld/go-ipld-prime"
|
||||||
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
"github.com/ipld/go-ipld-prime/codec/dagjson"
|
||||||
|
"github.com/ipld/go-ipld-prime/datamodel"
|
||||||
|
"github.com/ipld/go-ipld-prime/fluent/qp"
|
||||||
"github.com/ipld/go-ipld-prime/must"
|
"github.com/ipld/go-ipld-prime/must"
|
||||||
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
basicnode "github.com/ipld/go-ipld-prime/node/basic"
|
||||||
"github.com/ipld/go-ipld-prime/node/bindnode"
|
"github.com/ipld/go-ipld-prime/node/bindnode"
|
||||||
@@ -172,7 +174,7 @@ func TestSelect(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("slice on string", func(t *testing.T) {
|
t.Run("slice on string", func(t *testing.T) {
|
||||||
sel, err := Parse(`["foo"].[1:3]`)
|
sel, err := Parse(`.[1:3]`)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
node := basicnode.NewString("hello")
|
node := basicnode.NewString("hello")
|
||||||
@@ -182,11 +184,11 @@ func TestSelect(t *testing.T) {
|
|||||||
|
|
||||||
str, err := res.AsString()
|
str, err := res.AsString()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "el", str)
|
require.Equal(t, "el", str) // assert sliced substring
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("index on string", func(t *testing.T) {
|
t.Run("index on string", func(t *testing.T) {
|
||||||
sel, err := Parse(`["foo"].[2]`)
|
sel, err := Parse(`.[2]`)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
node := basicnode.NewString("hello")
|
node := basicnode.NewString("hello")
|
||||||
@@ -196,54 +198,68 @@ func TestSelect(t *testing.T) {
|
|||||||
|
|
||||||
str, err := res.AsString()
|
str, err := res.AsString()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "l", str)
|
require.Equal(t, "l", str) // assert indexed character
|
||||||
})
|
})
|
||||||
|
|
||||||
//t.Run("out of bounds slicing", func(t *testing.T) {
|
t.Run("out of bounds slicing", func(t *testing.T) {
|
||||||
// sel, err := Parse(`.[10:20]`)
|
node, err := qp.BuildList(basicnode.Prototype.Any, 3, func(la datamodel.ListAssembler) {
|
||||||
// require.NoError(t, err)
|
qp.ListEntry(la, qp.Int(1))
|
||||||
//
|
qp.ListEntry(la, qp.Int(2))
|
||||||
// node, err := qp.BuildList(basicnode.Prototype.Any, 3, func(la datamodel.ListAssembler) {
|
qp.ListEntry(la, qp.Int(3))
|
||||||
// qp.ListEntry(la, qp.Int(1))
|
})
|
||||||
// qp.ListEntry(la, qp.Int(2))
|
require.NoError(t, err)
|
||||||
// qp.ListEntry(la, qp.Int(3))
|
|
||||||
// })
|
sel, err := Parse(`.[10:20]`)
|
||||||
// require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
//
|
|
||||||
// res, err := sel.Select(node)
|
res, err := sel.Select(node)
|
||||||
// require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// require.NotEmpty(t, res)
|
require.NotEmpty(t, res)
|
||||||
//
|
require.Equal(t, int64(0), res.Length())
|
||||||
// bytes, err := res.AsBytes()
|
|
||||||
// require.NoError(t, err)
|
_, err = res.LookupByIndex(0)
|
||||||
//
|
require.ErrorIs(t, err, datamodel.ErrNotExists{}) // assert empty result for out of bounds slice
|
||||||
// list, err := qp.DecodeList(basicnode.Prototype.Any, bytes)
|
})
|
||||||
// require.NoError(t, err)
|
|
||||||
// require.Equal(t, 0, list.Length())
|
t.Run("backward slicing", func(t *testing.T) {
|
||||||
//})
|
node, err := qp.BuildList(basicnode.Prototype.Any, 3, func(la datamodel.ListAssembler) {
|
||||||
//
|
qp.ListEntry(la, qp.Int(1))
|
||||||
//t.Run("backward slicing", func(t *testing.T) {
|
qp.ListEntry(la, qp.Int(2))
|
||||||
// sel, err := Parse(`.[5:2]`)
|
qp.ListEntry(la, qp.Int(3))
|
||||||
// require.NoError(t, err)
|
})
|
||||||
//
|
require.NoError(t, err)
|
||||||
// node, err := qp.BuildList(basicnode.Prototype.Any, 3, func(la datamodel.ListAssembler) {
|
|
||||||
// qp.ListEntry(la, qp.Int(1))
|
sel, err := Parse(`.[5:2]`)
|
||||||
// qp.ListEntry(la, qp.Int(2))
|
require.NoError(t, err)
|
||||||
// qp.ListEntry(la, qp.Int(3))
|
|
||||||
// })
|
res, err := sel.Select(node)
|
||||||
// require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
//
|
require.NotEmpty(t, res)
|
||||||
// res, err := sel.Select(node)
|
require.Equal(t, int64(0), res.Length())
|
||||||
// require.NoError(t, err)
|
|
||||||
// require.NotEmpty(t, res)
|
_, err = res.LookupByIndex(0)
|
||||||
//
|
require.ErrorIs(t, err, datamodel.ErrNotExists{}) // assert empty result for backward slice
|
||||||
// bytes, err := res.AsBytes()
|
})
|
||||||
// require.NoError(t, err)
|
|
||||||
//
|
t.Run("slice with negative index", func(t *testing.T) {
|
||||||
// list, err := qp.DecodeList(basicnode.Prototype.Any, bytes)
|
node, err := qp.BuildList(basicnode.Prototype.Any, 3, func(la datamodel.ListAssembler) {
|
||||||
// require.NoError(t, err)
|
qp.ListEntry(la, qp.Int(1))
|
||||||
// require.Equal(t, 0, list.Length())
|
qp.ListEntry(la, qp.Int(2))
|
||||||
//})
|
qp.ListEntry(la, qp.Int(3))
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
sel, err := Parse(`.[0:-1]`)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
res, err := sel.Select(node)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, res)
|
||||||
|
|
||||||
|
val, err := res.LookupByIndex(1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 2, int(must.Int(val))) // Assert sliced value at index 1
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestMatch(t *testing.T) {
|
// func TestMatch(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user