github.com/qiniu/dyn@v1.3.0/text/subst_test.go (about)

     1  package text
     2  
     3  import (
     4  	"strings"
     5  	"syscall"
     6  	"testing"
     7  
     8  	"github.com/qiniu/x/errors"
     9  	"github.com/qiniu/x/ts"
    10  )
    11  
    12  func execOld(exprvar string, data interface{}, ft int) (val string, err error) {
    13  
    14  	for {
    15  		pos := strings.Index(exprvar, "$")
    16  		if pos < 0 {
    17  			return val + exprvar, nil
    18  		}
    19  
    20  		val += exprvar[:pos]
    21  		if pos+2 < len(exprvar) {
    22  			start := exprvar[pos+1]
    23  			switch start {
    24  			case '(', '{':
    25  				end := ")"
    26  				if start == '{' {
    27  					end = "}"
    28  				}
    29  				exprleft := exprvar[pos+2:]
    30  				pos2 := strings.Index(exprleft, end)
    31  				if pos2 >= 0 {
    32  					key2 := exprleft[:pos2]
    33  					val2, err2 := GetAsString(data, key2, ft, false)
    34  					if err2 != nil {
    35  						err = errors.Info(err2, "expr.Subst - GetAsString failed", key2).Detail(err2)
    36  						return
    37  					}
    38  					exprvar = exprleft[pos2+1:]
    39  					val += val2
    40  					continue
    41  				}
    42  			}
    43  		}
    44  		if pos+1 < len(exprvar) {
    45  			if exprvar[pos+1] == '$' {
    46  				exprvar = exprvar[pos+2:]
    47  				val += "$"
    48  				continue
    49  			}
    50  		}
    51  		err = errors.Info(syscall.EINVAL, "expr.Subst - invalid expr", exprvar[pos:])
    52  		break
    53  	}
    54  	return
    55  }
    56  
    57  var c1 = 1
    58  
    59  var data = map[string]interface{}{
    60  	"a": 1,
    61  	"b": func() interface{} {
    62  		return map[string]interface{}{
    63  			"c": func() interface{} {
    64  				c1++
    65  				return c1
    66  			},
    67  		}
    68  	},
    69  	"d": "12\\&3",
    70  }
    71  
    72  type testCase struct {
    73  	expr       string
    74  	result     string
    75  	resultForm string
    76  	resultText string
    77  }
    78  
    79  var cases = []testCase{
    80  	{"abc", "abc", "abc", "abc"},
    81  	{"abc $$ aaa", "abc $ aaa", "abc $ aaa", "abc $ aaa"},
    82  	{"abc $(b.c) aaa", "abc 2 aaa", "abc 3 aaa", "abc 4 aaa"},
    83  	{"abc $(d) aaa", "abc \"12\\\\&3\" aaa", "abc 12%5C%263 aaa", "abc 12\\&3 aaa"},
    84  	{"abc \"$(d)\" aaa", "abc \"12\\\\&3\" aaa", "abc \"12%5C%263\" aaa", "abc \"12\\&3\" aaa"},
    85  	{"$$", "$", "$", "$"},
    86  	{"$(b.c) aaa", "5 aaa", "6 aaa", "7 aaa"},
    87  	{"abc $(d)", "abc \"12\\\\&3\"", "abc 12%5C%263", "abc 12\\&3"},
    88  	{"abc=${e}&dee", "abc=null&dee", "abc=&dee", "abc=&dee"},
    89  }
    90  
    91  func TestExpr(t *testing.T) {
    92  
    93  	for _, c := range cases {
    94  		result, err := Subst(c.expr, data, Fmttype_Json, false)
    95  		if err != nil || result != c.result {
    96  			ts.Fatal(t, "Subst failed:", c.expr, "-", err, result, c.result)
    97  		}
    98  		result, err = Subst(c.expr, data, Fmttype_Form, false)
    99  		if err != nil || result != c.resultForm {
   100  			ts.Fatal(t, "Subst failed:", c.expr, "-", err, result, c.resultForm)
   101  		}
   102  		result, err = Subst(c.expr, data, Fmttype_Text, false)
   103  		if err != nil || result != c.resultText {
   104  			ts.Fatal(t, "Subst failed:", c.expr, "-", err, result, c.resultText)
   105  		}
   106  	}
   107  	_, err := Subst("abc=${e}&dee", data, Fmttype_Form, true)
   108  	if !errors.Is(err, syscall.ENOENT) {
   109  		ts.Fatal(t, "Subst failed:", err)
   110  	}
   111  }