Started working on 'try' statement
Build / build (push) Successful in 2m8s
Details
Build / build (push) Successful in 2m8s
Details
This commit is contained in:
parent
699ff18dab
commit
bb78a39cdb
|
@ -770,6 +770,71 @@ func ifBuiltin(ctx context.Context, args macroArgs) (object, error) {
|
|||
return nil, errors.New("malformed if-elif-else")
|
||||
}
|
||||
|
||||
func tryBuiltin(ctx context.Context, args macroArgs) (object, error) {
|
||||
if args.nargs() < 1 {
|
||||
return nil, errors.New("need at least 1 arguments")
|
||||
}
|
||||
|
||||
res, err := args.evalBlock(ctx, 0, nil, false)
|
||||
if err == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
args.shift(1)
|
||||
for args.identIs(ctx, 0, "catch") {
|
||||
args.shift(1)
|
||||
|
||||
if args.nargs() < 1 {
|
||||
return nil, errors.New("need at least 1 arguments")
|
||||
}
|
||||
|
||||
res, err := args.evalBlock(ctx, 0, nil, false)
|
||||
if err == nil {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
args.shift(2)
|
||||
}
|
||||
|
||||
// TODO: handle uncaught error
|
||||
|
||||
return nil, nil
|
||||
|
||||
/*
|
||||
if guard, err := args.evalArg(ctx, 0); err == nil && isTruthy(guard) {
|
||||
return args.evalBlock(ctx, 1, nil, false)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args.shift(2)
|
||||
for args.identIs(ctx, 0, "elif") {
|
||||
args.shift(1)
|
||||
|
||||
if args.nargs() < 2 {
|
||||
return nil, errors.New("need at least 2 arguments")
|
||||
}
|
||||
|
||||
if guard, err := args.evalArg(ctx, 0); err == nil && isTruthy(guard) {
|
||||
return args.evalBlock(ctx, 1, nil, false)
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args.shift(2)
|
||||
}
|
||||
|
||||
if args.identIs(ctx, 0, "else") && args.nargs() > 1 {
|
||||
return args.evalBlock(ctx, 1, nil, false)
|
||||
} else if args.nargs() == 0 {
|
||||
// no elif or else
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("malformed if-elif-else")
|
||||
*/
|
||||
}
|
||||
|
||||
func foreachBuiltin(ctx context.Context, args macroArgs) (object, error) {
|
||||
var (
|
||||
items object
|
||||
|
|
|
@ -88,6 +88,7 @@ func New(opts ...InstOption) *Inst {
|
|||
rootEC.addMacro("if", macroFunc(ifBuiltin))
|
||||
rootEC.addMacro("foreach", macroFunc(foreachBuiltin))
|
||||
rootEC.addMacro("proc", macroFunc(procBuiltin))
|
||||
rootEC.addMacro("try", macroFunc(tryBuiltin))
|
||||
|
||||
inst := &Inst{
|
||||
out: os.Stdout,
|
||||
|
|
|
@ -3,6 +3,7 @@ package ucl
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -36,6 +37,13 @@ func WithTestBuiltin() InstOption {
|
|||
return listObject(args.args), nil
|
||||
}))
|
||||
|
||||
i.rootEC.addCmd("error", invokableFunc(func(ctx context.Context, args invocationArgs) (object, error) {
|
||||
if len(args.args) == 0 {
|
||||
return nil, errors.New("an error occurred")
|
||||
}
|
||||
return nil, errors.New(args.args[0].String())
|
||||
}))
|
||||
|
||||
i.rootEC.addCmd("joinpipe", invokableFunc(func(ctx context.Context, args invocationArgs) (object, error) {
|
||||
sb := strings.Builder{}
|
||||
|
||||
|
@ -188,6 +196,52 @@ func TestBuiltins_If(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuiltins_Try(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
expr string
|
||||
want string
|
||||
}{
|
||||
{desc: "single try - successful", expr: `
|
||||
try {
|
||||
echo "good"
|
||||
}
|
||||
echo "after"`, want: "good\nafter\n(nil)\n"},
|
||||
{desc: "single try - unsuccessful", expr: `
|
||||
try {
|
||||
error "bang"
|
||||
}
|
||||
echo "after"`, want: "after\n(nil)\n"},
|
||||
{desc: "try with catch - successful", expr: `
|
||||
try {
|
||||
echo "good"
|
||||
} catch {
|
||||
echo "something happened"
|
||||
}
|
||||
echo "after"`, want: "good\nafter\n(nil)\n"},
|
||||
{desc: "try with catch - unsuccessful", expr: `
|
||||
try {
|
||||
error "bang"
|
||||
} catch {
|
||||
echo "something happened"
|
||||
}
|
||||
echo "after"`, want: "something happened\nafter\n(nil)\n"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
outW := bytes.NewBuffer(nil)
|
||||
|
||||
inst := New(WithOut(outW), WithTestBuiltin())
|
||||
err := EvalAndDisplay(ctx, inst, tt.expr)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.want, outW.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuiltins_ForEach(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
|
|
Loading…
Reference in New Issue