// scanner_test.go package text import ( "errors" "fmt" "strconv" "testing" ) type ctxExpType struct { BaseExpander funcs map[string]ExpanderFunc } func newCtxExp() *ctxExpType { return &ctxExpType{funcs: make(map[string]ExpanderFunc)} } func (ctx *ctxExpType) Handle(spec string, flags ScannerFlag) (value string, err error) { var f ExpanderFunc //fmt.Println("Spec:", spec) switch spec { case "value": value = "right-value" case "|ciao": value = "ciao" case `|__sum(1,2,3)`: if f, err = ctx.GetFunc("__sum"); err == nil { value, err = f(ctx, "", []string{"1", "2", "3"}) } case `|__cat(1,"2",3)`: if f, err = ctx.GetFunc("__cat"); err == nil { value, err = f(ctx, "", []string{"1", "2", "3"}) } case `uno|due`: value = "uno" case "|__xyz()": err = errors.New("unknown function __xyz") default: value = "" } return } func (ctx *ctxExpType) GetFunc(name string) (f ExpanderFunc, err error) { var ok bool if f, ok = ctx.funcs[name]; !ok { err = fmt.Errorf("function %s not found", name) } return } func (ctx *ctxExpType) AddFunc(name string, f ExpanderFunc, minArgs, maxArgs int, description string) { ctx.funcs[name] = f } func sum(ctx ExpanderContext, varValue string, args []string) (result string, err error) { if len(varValue) > 0 { result = varValue } else { var v int s := 0 for _, arg := range args { if v, err = strconv.Atoi(arg); err != nil { return } else { s += v } } result = strconv.Itoa(s) } return } func TestExpandStringTemplate(t *testing.T) { type inputType struct { ctx ExpanderContext source string wantResult string wantErr error } funcName := "scan" ctx := newCtxExp() ctx.AddFunc("__sum", sum, 1, 1, "fake function") inputs := []inputType{ {ctx, "this is the ${value}!", "this is the right-value!", nil}, {ctx, `pay \$31`, `pay $31`, nil}, {ctx, `\\regex\\`, `\regex\`, nil}, {ctx, `fake \x.`, `fake x.`, nil}, {ctx, ">${|ciao}<", ">ciao<", nil}, {ctx, `>${|__sum(1,2,3)}<`, ">6<", nil}, {ctx, `>${|__cat(1,"2",3)}<`, "", errors.New("function __cat not found")}, {ctx, `>${|__cat(1,"2",3)<`, "", errors.New("unbalanced open braces at offset 2")}, {ctx, `>${|__xyz()}<`, "", errors.New("unknown function __xyz")}, {ctx, `>${uno|due}<`, ">uno<", nil}, } for i, input := range inputs { gotResult, gotErr := ExpandStringTemplate(input.ctx, input.source) if gotResult != input.wantResult { t.Errorf("%d: %s(%q)/result = %q, want %q", i, funcName, input.source, gotResult, input.wantResult) } if gotErr == nil && input.wantErr == nil { continue } if (gotErr != nil && input.wantErr == nil) || (gotErr == nil && input.wantErr != nil) || (gotErr.Error() != input.wantErr.Error()) { t.Errorf("%d: %s(%q)/err = %v, want %v", i, funcName, input.source, gotErr, input.wantErr) } } }