Added test source files
This commit is contained in:
parent
a78c42a161
commit
d297530309
137
dict-set-context_test.go
Normal file
137
dict-set-context_test.go
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
// dict-set-context_test.go
|
||||||
|
package text
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewDictSetContext(t *testing.T) {
|
||||||
|
type inputType struct {
|
||||||
|
ctx ExpanderContext
|
||||||
|
source string
|
||||||
|
wantResult string
|
||||||
|
wantErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
funcName := "scan"
|
||||||
|
|
||||||
|
flags := DictSetFlag(0)
|
||||||
|
vars := map[string]string{"one": "1", "two": "2", "three": "3"}
|
||||||
|
ctx1 := NewDictSetContext(flags, vars)
|
||||||
|
ctx2 := NewDictSetContext(KeepVar, vars)
|
||||||
|
AddTimeFuncs(ctx2)
|
||||||
|
/*
|
||||||
|
err = fmt.Errorf("unsupported '%%%c' time specifier at %d", ch, i)
|
||||||
|
*/
|
||||||
|
now := time.Now()
|
||||||
|
yday := now.Add(-24*time.Hour)
|
||||||
|
inputs := []inputType{
|
||||||
|
{ctx2, `form: ${|__time-fmt now ""}`, fmt.Sprintf("form: %d-%02d-%02d %02d:%02d:%02d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second()), nil},
|
||||||
|
{ctx2, `form: ${|__time-fmt now "%-D"}`, fmt.Sprintf("form: %d-%d-%d", now.Year(), now.Month(), now.Day()), nil},
|
||||||
|
{ctx2, `form: ${|__time-fmt now "%:T"}`, fmt.Sprintf("form: %d:%d:%d", now.Hour(), now.Minute(), now.Second()), nil},
|
||||||
|
{ctx2, `form: ${|__time-fmt now "%02:T"}`,"", errors.New("invalid time specifier format at 3")},
|
||||||
|
{ctx2, `form: ${|__time-fmt ""}`,"", errors.New("time value is empty")},
|
||||||
|
{ctx2, `form: ${|__time-fmt yesterday "%-D"}`, fmt.Sprintf("form: %d-%d-%d", yday.Year(), yday.Month(), yday.Day()), nil},
|
||||||
|
{ctx1, "${one|pippo}", "1", nil},
|
||||||
|
{ctx1, "${one|__default pluto}", "1", nil},
|
||||||
|
{ctx1, "${six|__default pluto}", "pluto", nil},
|
||||||
|
{ctx1, "${six|__default - pluto paperino|__lower|__upper}", "PLUTO-PAPERINO", nil},
|
||||||
|
{ctx1, "${two|__join + 1 ${.} ${|__get three}}", "1+2+3", nil},
|
||||||
|
{ctx1, "${=one|__get}", "1", nil},
|
||||||
|
{ctx1, "${|__get unknown default}", "default", nil},
|
||||||
|
{ctx1, "${one|__set A ${.}}", "1", nil},
|
||||||
|
{ctx1, "${one|__set B }", "1", nil},
|
||||||
|
{ctx1, "${one|__set}", "1", nil},
|
||||||
|
{ctx1, "${=archive.tar.gz|__trim-suffix}", "archive.tar", nil},
|
||||||
|
{ctx1, "${=prog.exe|__trim-suffix .zip .png .exe .com}", "prog", nil},
|
||||||
|
{ctx1, "${=prog.exe|__trim-suffix .zip .png .jpeg .com}", "prog.exe", nil},
|
||||||
|
{ctx1, "${=ciccio}", "ciccio", nil},
|
||||||
|
{ctx1, "${=ciccio{}", "", errors.New("unbalanced open braces at offset 9")},
|
||||||
|
{ctx1, "${|__get two}", "2", nil},
|
||||||
|
{ctx1, "${one} + ${two} = ${three}", "1 + 2 = 3", nil},
|
||||||
|
{ctx1, "${one} + ${two} = ${four}", "1 + 2 = ", nil},
|
||||||
|
{ctx2, "${one} + ${two} = ${four}", "1 + 2 = ${four}", nil},
|
||||||
|
{ctx2, `now: ${|__time-fmt now "%:02T"}`, fmt.Sprintf("now: %02d:%02d:%02d", now.Hour(), now.Minute(), now.Second()), nil},
|
||||||
|
{ctx2, `hour: ${|__time-fmt now "%02H"}`, fmt.Sprintf("hour: %02d", now.Hour()), nil},
|
||||||
|
{ctx2, `minute: ${|__time-fmt now "%02M"}`, fmt.Sprintf("minute: %02d", now.Minute()), nil},
|
||||||
|
{ctx2, `second: ${|__time-fmt now "%02S" }`, fmt.Sprintf("second: %02d", now.Second()), nil},
|
||||||
|
{ctx2, `today: ${|__time-fmt now "%-02D"}`, fmt.Sprintf("today: %d-%02d-%02d", now.Year(), now.Month(), now.Day()), nil},
|
||||||
|
{ctx2, `year: ${|__time-fmt now "%Y"}`, fmt.Sprintf("year: %d", now.Year()), nil},
|
||||||
|
{ctx2, `month: ${|__time-fmt now "%m"}`, fmt.Sprintf("month: %02d", now.Month()), nil},
|
||||||
|
{ctx2, `weird: ${|__time-fmt now "%c"}`, "", errors.New(`unsupported 'c' time specifier at "%c"/2`)},
|
||||||
|
{ctx2, `perc: ${|__time-fmt now "%%"}`, "perc: %", nil},
|
||||||
|
{ctx1, `unknown var ${!unknown}`, ``, errors.New(`the variable specification "unknown" requires a value`)},
|
||||||
|
{ctx1, `${hello-word|}!`, `!`, nil},
|
||||||
|
{ctx1, `${hello-word|ciao}!`, `ciao!`, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCheckNumArgs(t *testing.T) {
|
||||||
|
type inputType struct {
|
||||||
|
info ExpanderFuncBlock
|
||||||
|
n int // number of args
|
||||||
|
want bool
|
||||||
|
}
|
||||||
|
funcName := "CheckNumArgs"
|
||||||
|
|
||||||
|
inputs := []inputType{
|
||||||
|
{ExpanderFuncBlock{"", nil, -1, -1, ""}, 0, true},
|
||||||
|
{ExpanderFuncBlock{"", nil, 0, -1, ""}, 10, true},
|
||||||
|
{ExpanderFuncBlock{"", nil, 2, 4, ""}, 1, false},
|
||||||
|
}
|
||||||
|
for i, input := range inputs {
|
||||||
|
got := input.info.CheckNumArgs(input.n)
|
||||||
|
|
||||||
|
if got != input.want {
|
||||||
|
t.Errorf("%d: %s(%d)/result = %v, want %v", i, funcName, input.n, got, input.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIterateFunc(t *testing.T) {
|
||||||
|
var sb strings.Builder
|
||||||
|
|
||||||
|
funcName := "IterateFunc"
|
||||||
|
|
||||||
|
want := "f141c5fa802ed509c08ec057eea5ba0086a84b21"
|
||||||
|
vars := map[string]string{"one": "1", "two": "2", "three": "3"}
|
||||||
|
ctx := NewDictSetContext(KeepVar, vars)
|
||||||
|
ctx.AddFunc("dumm1", nil, 1, 2, "bla-bla")
|
||||||
|
ctx.AddFunc("dumm2", nil, 0, 5, strings.Repeat(".", 81))
|
||||||
|
ctx.AddFunc("dumm3", nil, -1, -1, "bla-bla")
|
||||||
|
ctx.AddFunc("dumm4", nil, 2, -1, "bla-bla")
|
||||||
|
|
||||||
|
ctx.IterateFunc(func(info *ExpanderFuncBlock) error {
|
||||||
|
sb.WriteString(info.String())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
hasher := sha1.New()
|
||||||
|
hasher.Write([]byte(sb.String()))
|
||||||
|
got := hex.EncodeToString(hasher.Sum(nil))
|
||||||
|
//fmt.Println("sha:", got)
|
||||||
|
//fmt.Println(sb.String())
|
||||||
|
if got != want {
|
||||||
|
t.Errorf("%s()/result = %q, want %q", funcName, got, want)
|
||||||
|
}
|
||||||
|
}
|
2
expander-context_test.go
Normal file
2
expander-context_test.go
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// expander-context_test.go
|
||||||
|
package text
|
114
expander_test.go
Normal file
114
expander_test.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
scanner_test.go
Normal file
120
scanner_test.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
tty_test.go
Normal file
27
tty_test.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// expander-context_test.go
|
||||||
|
package text
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSprintf(t *testing.T) {
|
||||||
|
list := []string{
|
||||||
|
"ciao #{c(red);i}Mario#. #{u;b}Come# #{GREEN;b}Stai#{.}?",
|
||||||
|
"ciao #{c(red)i-Mario}. #{ub-Come} #{GREEN;b-Stai#}?",
|
||||||
|
}
|
||||||
|
//s := Sprintf("ciao #{fg(139);i}Mario#. #{u;b}Come# #{GREEN;b}%s#{.}?", "Stai")
|
||||||
|
fmt.Println("--- Sprintf() ---")
|
||||||
|
for i, s := range list {
|
||||||
|
x := Sprintf(s)
|
||||||
|
fmt.Printf("--- Test nr %d: %q\n", i+1, s)
|
||||||
|
fmt.Println(x)
|
||||||
|
}
|
||||||
|
fmt.Println("\n--- Sprintf() ---")
|
||||||
|
for i, s := range list {
|
||||||
|
fmt.Printf("--- Test nr %d: %q\n", i+1, s)
|
||||||
|
Fprintf(os.Stdout, s)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user