diff --git a/dict_test.go b/dict_test.go new file mode 100644 index 0000000..93aa413 --- /dev/null +++ b/dict_test.go @@ -0,0 +1,115 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// dict_test.go +package expr + +import ( + "errors" + + "strings" + "testing" +) + +func TestDictParser(t *testing.T) { + section := "Dict" + + type inputType struct { + source string + wantResult any + wantErr error + } + + inputs := []inputType{ + /* 1 */ {`{}`, map[any]any{}, nil}, + /* 2 */ {`{123}`, nil, errors.New(`[1:6] expected ":", got "}"`)}, + /* 3 */ {`{1:"one",2:"two",3:"three"}`, map[int64]any{int64(1):"one", int64(2):"two", int64(3):"three"}, nil}, + /* 4 */ {`{1:"one",2:"two",3:"three"}.2`, "three", nil}, + // /* 3 */ {`[1,2,"hello"]`, []any{int64(1), int64(2), "hello"}, nil}, + // /* 4 */ {`[1+2, not true, "hello"]`, []any{int64(3), false, "hello"}, nil}, + // /* 5 */ {`[1,2]+[3]`, []any{int64(1), int64(2), int64(3)}, nil}, + // /* 6 */ {`[1,4,3,2]-[3]`, []any{int64(1), int64(4), int64(2)}, nil}, + // /* 7 */ {`add([1,4,3,2])`, int64(10), nil}, + // /* 8 */ {`add([1,[2,2],3,2])`, int64(10), nil}, + // /* 9 */ {`mul([1,4,3.0,2])`, float64(24.0), nil}, + // /* 10 */ {`add([1,"hello"])`, nil, errors.New(`add(): param nr 2 (2 in 1) has wrong type string, number expected`)}, + // /* 11 */ {`[a=1,b=2,c=3] but a+b+c`, int64(6), nil}, + // /* 12 */ {`[1,2,3] << 2+2`, []any{int64(1), int64(2), int64(3), int64(4)}, nil}, + // /* 13 */ {`2-1 >> [2,3]`, []any{int64(1), int64(2), int64(3)}, nil}, + // /* 14 */ {`[1,2,3].1`, int64(2), nil}, + // /* 15 */ {`ls=[1,2,3] but ls.1`, int64(2), nil}, + // /* 16 */ {`ls=[1,2,3] but ls.(-1)`, int64(3), nil}, + } + + succeeded := 0 + failed := 0 + + // inputs1 := []inputType{ + // /* 7 */ {`add([1,4,3,2])`, int64(10), nil}, + // } + + for i, input := range inputs { + var expr *ast + var gotResult any + var gotErr error + + ctx := NewSimpleFuncStore() + ctx.SetVar("var1", int64(123)) + ctx.SetVar("var2", "abc") + ImportMathFuncs(ctx) + parser := NewParser(ctx) + + logTest(t, i+1, "Dict", input.source, input.wantResult, input.wantErr) + + r := strings.NewReader(input.source) + scanner := NewScanner(r, DefaultTranslations()) + + good := true + if expr, gotErr = parser.Parse(scanner); gotErr == nil { + gotResult, gotErr = expr.Eval(ctx) + } + + if (gotResult == nil && input.wantResult != nil) || (gotResult != nil && input.wantResult == nil) { + t.Errorf("%d: %q -> result = %v [%T], want %v [%T]", i+1, input.source, gotResult, gotResult, input.wantResult, input.wantResult) + good = false + } + + if gotList, okGot := gotResult.([]any); okGot { + if wantList, okWant := input.wantResult.([]any); okWant { + if (gotList == nil && wantList != nil) || (gotList != nil && wantList == nil) { + t.Errorf("%d: %q -> result = %v [%T], want %v [%T]", i+1, input.source, gotResult, gotResult, input.wantResult, input.wantResult) + good = false + } else { + equal := len(gotList) == len(wantList) + if equal { + for i, gotItem := range gotList { + wantItem := wantList[i] + equal = gotItem == wantItem + if !equal { + break + } + } + } + if !equal { + t.Errorf("%d: %q -> result = %v [%T], want %v [%T]", i+1, input.source, gotResult, gotResult, input.wantResult, input.wantResult) + good = false + } + } + } + } + + if gotErr != input.wantErr { + if input.wantErr == nil || gotErr == nil || (gotErr.Error() != input.wantErr.Error()) { + t.Errorf("%d: %q -> err = <%v>, want <%v>", i+1, input.source, gotErr, input.wantErr) + good = false + } + } + + if good { + succeeded++ + } else { + failed++ + } + } + t.Logf("%s -- test count: %d, succeeded: %d, failed: %d", section, len(inputs), succeeded, failed) +}