Fixed NPE when trying to bind string value to nil
Build / build (push) Successful in 2m14s Details

This commit is contained in:
Leon Mika 2024-08-31 10:27:38 +10:00
parent f322834cef
commit 7fafc23401
2 changed files with 61 additions and 22 deletions

View File

@ -111,7 +111,11 @@ func (ca CallArgs) bindArg(v interface{}, arg object) error {
} }
return nil return nil
case *string: case *string:
*t = arg.String() if arg != nil {
*t = arg.String()
} else {
*t = ""
}
case *int: case *int:
if iArg, ok := arg.(intObject); ok { if iArg, ok := arg.(intObject); ok {
*t = int(iArg) *t = int(iArg)

View File

@ -81,6 +81,7 @@ func TestInst_SetBuiltin(t *testing.T) {
{"plain eval", `add2 -sep ", " -right "world" -left "Hello"`, "Hello, world"}, {"plain eval", `add2 -sep ", " -right "world" -left "Hello"`, "Hello, world"},
{"swap 1", `add2 -right "right" -left "left" -sep ":"`, "left:right"}, {"swap 1", `add2 -right "right" -left "left" -sep ":"`, "left:right"},
{"swap 2", `add2 -left "left" -sep ":" -right "right" -upcase`, "LEFT:RIGHT"}, {"swap 2", `add2 -left "left" -sep ":" -right "right" -upcase`, "LEFT:RIGHT"},
{"nil 1", `add2 -right "right" -left () -sep ":"`, ":right"},
} }
for _, tt := range tests { for _, tt := range tests {
@ -186,32 +187,66 @@ func TestInst_SetBuiltin(t *testing.T) {
} }
func TestCallArgs_Bind(t *testing.T) { func TestCallArgs_Bind(t *testing.T) {
ctx := context.Background() t.Run("happy path", func(t *testing.T) {
ctx := context.Background()
inst := ucl.New() inst := ucl.New()
inst.SetBuiltin("sa", func(ctx context.Context, args ucl.CallArgs) (any, error) { inst.SetBuiltin("sa", func(ctx context.Context, args ucl.CallArgs) (any, error) {
return doStringA{this: "a val"}, nil return doStringA{this: "a val"}, nil
}) })
inst.SetBuiltin("sb", func(ctx context.Context, args ucl.CallArgs) (any, error) { inst.SetBuiltin("sb", func(ctx context.Context, args ucl.CallArgs) (any, error) {
return doStringB{left: "foo", right: "bar"}, nil return doStringB{left: "foo", right: "bar"}, nil
}) })
inst.SetBuiltin("dostr", func(ctx context.Context, args ucl.CallArgs) (any, error) { inst.SetBuiltin("dostr", func(ctx context.Context, args ucl.CallArgs) (any, error) {
var ds doStringable var ds doStringable
if err := args.Bind(&ds); err != nil { if err := args.Bind(&ds); err != nil {
return nil, err return nil, err
}
return ds.DoString(), nil
})
va, err := inst.Eval(ctx, `dostr (sa)`)
assert.NoError(t, err)
assert.Equal(t, "do string A: a val", va)
vb, err := inst.Eval(ctx, `dostr (sb)`)
assert.NoError(t, err)
assert.Equal(t, "do string B: foo bar", vb)
})
t.Run("bind to string", func(t *testing.T) {
tests := []struct {
descr string
eval string
want string
}{
{descr: "string value", eval: `sa "hello"`, want: "[hello]"},
{descr: "int value", eval: `sa 13245`, want: "[13245]"},
{descr: "nil value", eval: `sa ()`, want: "[]"},
} }
return ds.DoString(), nil for _, tt := range tests {
t.Run(tt.descr, func(t *testing.T) {
ctx := context.Background()
inst := ucl.New()
inst.SetBuiltin("sa", func(ctx context.Context, args ucl.CallArgs) (any, error) {
var v string
if err := args.Bind(&v); err != nil {
return nil, err
}
return fmt.Sprintf("[%v]", v), nil
})
res, err := inst.Eval(ctx, tt.eval)
assert.NoError(t, err)
assert.Equal(t, tt.want, res)
})
}
}) })
va, err := inst.Eval(ctx, `dostr (sa)`)
assert.NoError(t, err)
assert.Equal(t, "do string A: a val", va)
vb, err := inst.Eval(ctx, `dostr (sb)`)
assert.NoError(t, err)
assert.Equal(t, "do string B: foo bar", vb)
} }
func TestCallArgs_CanBind(t *testing.T) { func TestCallArgs_CanBind(t *testing.T) {