Skip to content

Commit

Permalink
code(builtin) - add reverse function
Browse files Browse the repository at this point in the history
  • Loading branch information
PxyUp committed Feb 8, 2024
1 parent c7658ac commit 8609bca
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
35 changes: 35 additions & 0 deletions builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,41 @@ var Builtins = []*Function{
return anyType, fmt.Errorf("cannot transform %s from pairs", args[0])
},
},
{
Name: "reverse",
Func: func(args ...any) (any, error) {
if len(args) != 1 {
return nil, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}

v := reflect.ValueOf(args[0])
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
return nil, fmt.Errorf("cannot reverse %s", v.Kind())
}

arr := make([]any, v.Len())

size := v.Len()

for i := 0; i < size; i++ {
arr[i] = v.Index(size - i - 1).Interface()
}

return arr, nil

},
Validate: func(args []reflect.Type) (reflect.Type, error) {
if len(args) != 1 {
return anyType, fmt.Errorf("invalid number of arguments (expected 1, got %d)", len(args))
}
switch kind(args[0]) {
case reflect.Interface, reflect.Slice, reflect.Array:
default:
return anyType, fmt.Errorf("cannot reverse %s", args[0])
}
return arrayType, nil
},
},
{
Name: "sort",
Func: func(args ...any) (any, error) {
Expand Down
32 changes: 32 additions & 0 deletions builtin/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,38 @@ func TestBuiltin_type(t *testing.T) {
}
}

func TestBuiltin_reverse(t *testing.T) {
env := map[string]any{
"ArrayOfString": []string{"foo", "bar", "baz"},
"ArrayOfInt": []int{2, 1, 3},
"ArrayOfFloat": []float64{3.0, 2.0, 1.0},
"ArrayOfFoo": []mock.Foo{{Value: "c"}, {Value: "a"}, {Value: "b"}},
}
tests := []struct {
input string
want any
}{
{`reverse([])`, []any{}},
{`reverse(ArrayOfInt)`, []any{3, 1, 2}},
{`reverse(ArrayOfFloat)`, []any{1.0, 2.0, 3.0}},
{`reverse(ArrayOfFoo)`, []any{mock.Foo{Value: "b"}, mock.Foo{Value: "a"}, mock.Foo{Value: "c"}}},
{`reverse([[1,2], [2,2]])`, []any{[]any{2, 2}, []any{1, 2}}},
{`reverse(reverse([[1,2], [2,2]]))`, []any{[]any{1, 2}, []any{2, 2}}},
{`reverse([{"test": true}, {id:4}, {name: "value"}])`, []any{map[string]any{"name": "value"}, map[string]any{"id": 4}, map[string]any{"test": true}}},
}

for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
program, err := expr.Compile(test.input, expr.Env(env))
require.NoError(t, err)

out, err := expr.Run(program, env)
require.NoError(t, err)
assert.Equal(t, test.want, out)
})
}
}

func TestBuiltin_sort(t *testing.T) {
env := map[string]any{
"ArrayOfString": []string{"foo", "bar", "baz"},
Expand Down

0 comments on commit 8609bca

Please sign in to comment.