// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // scanner_test.go package text import ( "errors" "testing" ) func TestGetVarSpec(t *testing.T) { type inputGetVarSpec struct { source string offset int wantSpec string wantFlags ScannerFlag wantOffset int wantErr error } funcName := "getVarSpec" inputs := []inputGetVarSpec{ {"Hello ${name}.", 7, "name", ScannerFlag(0), 13, nil}, {"one ${!varspec}", 5, "varspec", ValueRequired, 15, nil}, {"one ${*varspec}", 5, "varspec", EncryptValue, 15, nil}, {"one ${*!varspec}", 5, "varspec", ValueRequired | EncryptValue, 16, nil}, {"one ${*!var{spec}", 5, "", ValueRequired | EncryptValue, 17, errors.New("unbalanced open braces at offset 11")}, {"one ${two}${three}", 11, "three", ScannerFlag(0), 18, nil}, {"one $2${three}", 5, "2", ScannerFlag(0), 6, nil}, {"one $!2${three}", 5, "", ScannerFlag(0), 5, nil}, {"one $2{3}${three}", 5, "2", ScannerFlag(0), 6, nil}, {"one ${{2}}{3}${three}", 5, "{2}", ScannerFlag(0), 10, nil}, {">${|ciao}<", 2, "|ciao", ScannerFlag(0), 9, nil}, {">${|{ciao}<", 2, "", ScannerFlag(0), 11, errors.New("unbalanced open braces at offset 4")}, } for i, input := range inputs { gotSpec, gotFlags, gotOffset, gotErr := getVarSpec(input.source, input.offset) if gotSpec != input.wantSpec { t.Errorf("%d: %s(%q, %d)/spec = %q, want %q", i, funcName, input.source, input.offset, gotSpec, input.wantSpec) } if gotFlags != input.wantFlags { t.Errorf("%d: %s(%q, %d)/flags = %d, want %d", i, funcName, input.source, input.offset, gotFlags, input.wantFlags) } if gotOffset != input.wantOffset { t.Errorf("%d: %s(%q, %d)/offset = %d, want %d", i, funcName, input.source, input.offset, gotOffset, input.wantOffset) } 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, %d)/err = %v, want %v", i, funcName, input.source, input.offset, gotErr, input.wantErr) } } } type ctxType struct{} func (ctx *ctxType) Handle(spec string, flags ScannerFlag) (value string, err error) { //fmt.Println("Spec:", spec) switch spec { case "value": value = "right-value" case "|ciao": value = "ciao" case `|__sum(1,2,3)`: value = "6" case `|__cat(1,"2",3)`: value = "123" case `uno|due`: value = "uno" case "|__xyz()": err = errors.New("unknown function __xyz") default: value = "" } return } func TestScan(t *testing.T) { type inputType struct { ctx VariableHandler source string wantResult string wantErr error } funcName := "scan" inputs := []inputType{ {&ctxType{}, "this is the ${value}!", "this is the right-value!", nil}, {&ctxType{}, `pay \$31`, `pay $31`, nil}, {&ctxType{}, `\\regex\\`, `\regex\`, nil}, {&ctxType{}, `fake \x.`, `fake x.`, nil}, {&ctxType{}, ">${|ciao}<", ">ciao<", nil}, {&ctxType{}, `>${|__sum(1,2,3)}<`, ">6<", nil}, {&ctxType{}, `>${|__cat(1,"2",3)}<`, ">123<", nil}, {&ctxType{}, `>${|__cat(1,"2",3)<`, "", errors.New("unbalanced open braces at offset 2")}, {&ctxType{}, `>${|__xyz()}<`, "", errors.New("unknown function __xyz")}, {&ctxType{}, `>${uno|due}<`, ">uno<", nil}, } for i, input := range inputs { gotResult, gotErr := Scan(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) } } }