Added the keys built-in

This commit is contained in:
Leon Mika 2024-05-10 00:10:42 +00:00
parent 34a0c8e3ff
commit ad746c05aa
3 changed files with 80 additions and 1 deletions

View File

@ -165,6 +165,29 @@ func indexBuiltin(ctx context.Context, args invocationArgs) (object, error) {
return val, nil
}
func keysBuiltin(ctx context.Context, args invocationArgs) (object, error) {
if err := args.expectArgn(1); err != nil {
return nil, err
}
val := args.args[0]
switch v := val.(type) {
case hashable:
keys := make(listObject, 0, v.Len())
if err := v.Each(func(k string, _ object) error {
keys = append(keys, strObject(k))
return nil
}); err != nil {
return nil, err
}
return keys, nil
default:
return nil, nil
}
return nil, nil
}
func mapBuiltin(ctx context.Context, args invocationArgs) (object, error) {
if err := args.expectArgn(2); err != nil {
return nil, err

View File

@ -50,6 +50,7 @@ func New(opts ...InstOption) *Inst {
rootEC.addCmd("set", invokableFunc(setBuiltin))
rootEC.addCmd("toUpper", invokableFunc(toUpperBuiltin))
rootEC.addCmd("len", invokableFunc(lenBuiltin))
rootEC.addCmd("keys", invokableFunc(keysBuiltin))
rootEC.addCmd("index", invokableFunc(indexBuiltin))
rootEC.addCmd("call", invokableFunc(callBuiltin))

View File

@ -4,9 +4,10 @@ import (
"bytes"
"context"
"fmt"
"github.com/stretchr/testify/assert"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
// Builtins used for test
@ -642,3 +643,57 @@ func TestBuiltins_Len(t *testing.T) {
})
}
}
func TestBuiltins_Keys(t *testing.T) {
type testNested struct {
Nested string
Type string
}
tests := []struct {
desc string
expr string
wantItems []string
}{
{desc: "keys of map", expr: `keys [alpha: "hello" bravo: "world"]`, wantItems: []string{"alpha", "bravo"}},
{desc: "keys of go struct 1", expr: `goStruct | keys`, wantItems: []string{"Alpha", "Beta", "Gamma"}},
{desc: "keys of go struct 2", expr: `index (goStruct) Gamma | keys`, wantItems: []string{"Nested", "Type"}},
}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
ctx := context.Background()
outW := bytes.NewBuffer(nil)
inst := New(WithOut(outW), WithTestBuiltin())
inst.SetBuiltin("goInt", func(ctx context.Context, args CallArgs) (any, error) {
return []int{6, 5, 4}, nil
})
inst.SetBuiltin("goStruct", func(ctx context.Context, args CallArgs) (any, error) {
return struct {
Alpha string
Beta string
Gamma testNested
hidden string
missing string
}{
Alpha: "foo",
Beta: "bar",
Gamma: testNested{
Nested: "ads",
Type: "asd",
},
hidden: "hidden",
missing: "missing",
}, nil
})
res, err := inst.Eval(ctx, tt.expr)
assert.NoError(t, err)
assert.Len(t, res, len(tt.wantItems))
for _, i := range tt.wantItems {
assert.Contains(t, res, i)
}
})
}
}