// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // t_funcs_test.go package expr import ( "errors" "testing" ) func TestFuncs(t *testing.T) { section := "Funcs" inputs := []inputType{ /* 1 */ {`two=func(){2}; two()`, int64(2), nil}, /* 2 */ {`double=func(x) {2*x}; (double(3))`, int64(6), nil}, /* 3 */ {`double=func(x){2*x}; double(3)`, int64(6), nil}, /* 4 */ {`double=func(x){2*x}; a=5; double(3+a) + 1`, int64(17), nil}, /* 5 */ {`double=func(x){2*x}; a=5; two=func() {2}; (double(3+a) + 1) * two()`, int64(34), nil}, /* 6 */ {`@x="hello"; @x`, nil, errors.New(`[1:3] variable references are not allowed in top level expressions: "@x"`)}, /* 7 */ {`f=func(){@x="hello"}; f(); x`, "hello", nil}, /* 8 */ {`f=func(@y){@y=@y+1}; f(2); y`, int64(3), nil}, /* 9 */ {`f=func(@y){g=func(){@x=5}; @y=@y+g()}; f(2); y+x`, nil, errors.New(`undefined variable or function "x"`)}, /* 10 */ {`f=func(@y){g=func(){@x=5}; @z=g(); @y=@y+@z}; f(2); y+z`, int64(12), nil}, /* 11 */ {`f=func(@y){g=func(){@x=5}; g(); @z=x; @y=@y+@z}; f(2); y+z`, int64(12), nil}, /* 12 */ {`f=func(@y){g=func(){@x=5}; g(); @z=x; @x=@y+@z}; f(2); y+x`, int64(9), nil}, /* 13 */ {`two=func(){2}; four=func(f){f()+f()}; four(two)`, int64(4), nil}, /* 14 */ {`two=func(){2}; two(123)`, nil, errors.New(`two(): too much params -- expected 0, got 1`)}, } t.Setenv("EXPR_PATH", ".") // parserTestSpec(t, section, inputs, 69) parserTest(t, section, inputs) } func dummy(ctx ExprContext, name string, args []any) (result any, err error) { return } func TestFunctionToStringSimple(t *testing.T) { source := newGolangFunctor(dummy) want := "func() {<body>}" got := source.ToString(0) if got != want { t.Errorf(`(func() -> result = %v [%T], want = %v [%T]`, got, got, want, want) } } func TestFunctionGetFunc(t *testing.T) { source := newGolangFunctor(dummy) want := ExprFunc(nil) got := source.GetFunc() if got != want { t.Errorf(`(func() -> result = %v [%T], want = %v [%T]`, got, got, want, want) } }