2024-02-12 03:04:07 +00:00
|
|
|
package salix
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"go.elara.ws/salix/ast"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestFuncCall(t *testing.T) {
|
|
|
|
const expected = 1 + 2i
|
|
|
|
fn := func() complex128 { return expected }
|
|
|
|
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
val, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("execFuncCall error: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if val.(complex128) != expected {
|
|
|
|
t.Errorf("Expected %v, got %v", expected, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-12 18:51:28 +00:00
|
|
|
func TestFuncCallInvalidParamCount(t *testing.T) {
|
|
|
|
fn := func() int { return 0 }
|
|
|
|
|
|
|
|
// test("string")
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Params: []ast.Node{
|
|
|
|
ast.String{Value: "string", Position: testPos(t)},
|
|
|
|
},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if err == nil {
|
|
|
|
t.Error("Expected error, got nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallInvalidParamType(t *testing.T) {
|
|
|
|
fn := func(i int) int { return i }
|
|
|
|
|
|
|
|
// test("string")
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Params: []ast.Node{
|
|
|
|
ast.String{Value: "string", Position: testPos(t)},
|
|
|
|
},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if err == nil {
|
|
|
|
t.Error("Expected error, got nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-12 03:04:07 +00:00
|
|
|
func TestFuncCallVariadic(t *testing.T) {
|
|
|
|
const expected = "Hello, World"
|
|
|
|
concat := func(params ...string) string { return strings.Join(params, ", ") }
|
|
|
|
|
|
|
|
// concat("Hello", "World")
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "concat", Position: testPos(t)},
|
|
|
|
Params: []ast.Node{
|
|
|
|
ast.String{Value: "Hello", Position: testPos(t)},
|
|
|
|
ast.String{Value: "World", Position: testPos(t)},
|
|
|
|
},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
val, err := tmpl.execFuncCall(ast, map[string]any{"concat": concat})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("execFuncCall error: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if val.(string) != expected {
|
|
|
|
t.Errorf("Expected %q, got %q", expected, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallError(t *testing.T) {
|
2024-02-12 18:53:12 +00:00
|
|
|
expectedErr := errors.New("expected error")
|
2024-02-12 03:04:07 +00:00
|
|
|
fn := func() error { return expectedErr }
|
|
|
|
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if !errors.Is(err, expectedErr) {
|
|
|
|
t.Errorf("Expected %q, got %q", expectedErr, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallMultiReturn(t *testing.T) {
|
|
|
|
const expected = "test"
|
|
|
|
fn := func() (string, error) { return expected, nil }
|
|
|
|
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
val, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("execFuncCall error: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if val.(string) != expected {
|
|
|
|
t.Errorf("Expected %q, got %q", expected, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallMultiReturnError(t *testing.T) {
|
2024-02-12 18:53:12 +00:00
|
|
|
expectedErr := errors.New("expected error")
|
2024-02-12 03:04:07 +00:00
|
|
|
fn := func() (string, error) { return "", expectedErr }
|
|
|
|
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if !errors.Is(err, expectedErr) {
|
|
|
|
t.Errorf("Expected %q, got %q", expectedErr, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallNil(t *testing.T) {
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": nil})
|
|
|
|
if err == nil {
|
|
|
|
t.Error("Expected error, got nil")
|
|
|
|
}
|
|
|
|
}
|
2024-02-12 18:51:28 +00:00
|
|
|
|
|
|
|
func TestFuncCallNotFound(t *testing.T) {
|
|
|
|
// test()
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{})
|
|
|
|
if err == nil {
|
|
|
|
t.Error("Expected error, got nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFuncCallAssignment(t *testing.T) {
|
|
|
|
fn := func(i int) int { return i }
|
|
|
|
|
|
|
|
// test(x = 1)
|
|
|
|
ast := ast.FuncCall{
|
|
|
|
Name: ast.Ident{Value: "test", Position: testPos(t)},
|
|
|
|
Params: []ast.Node{
|
|
|
|
ast.Assignment{
|
|
|
|
Name: ast.Ident{Value: "x", Position: testPos(t)},
|
|
|
|
Value: ast.Integer{Value: 1, Position: testPos(t)},
|
|
|
|
Position: testPos(t),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Position: testPos(t),
|
|
|
|
}
|
|
|
|
|
|
|
|
tmpl := testTmpl(t)
|
|
|
|
_, err := tmpl.execFuncCall(ast, map[string]any{"test": fn})
|
|
|
|
if err == nil {
|
|
|
|
t.Error("Expected error, got nil")
|
|
|
|
}
|
|
|
|
}
|