diff --git a/demo/advanced.yaml b/demo/advanced.yaml index a1754922087641abc4c9b770c585b10f7ad93d63..27cbc974552b2ae43b97ad816f4621415b23707e 100644 --- a/demo/advanced.yaml +++ b/demo/advanced.yaml @@ -24,9 +24,10 @@ fields: postfix: "]\t" - field: field_value # 引用同文件其他字段进行数学运算。 - value: "$field_step_negative * 2 - 1" + value: "($field_step_negative * $field_nested_range) * -1 + 1000" prefix: "[" postfix: "]\t" + length: 20 - field: field_nested_range from: zentao.number.v1.yaml # 引用用户自定义ranges,存于users目录下。 diff --git a/go.mod b/go.mod index b2e572883abc14e900b9750f2a06852d4bf3f87e..ef85d676d94ed0aad316fc923ebd0f185a816310 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require golang.org/x/text v0.3.3 require ( github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.0 github.com/Chain-Zhang/pinyin v0.1.3 + github.com/Knetic/govaluate v3.0.0+incompatible github.com/akavel/rsrc v0.9.0 // indirect github.com/emirpasic/gods v1.12.0 github.com/fatih/color v1.9.0 diff --git a/go.sum b/go.sum index a59e6404c9ab1bfbfb3e907c1d5281c9e866a911..15fbae61b34c14d9a064db31a15e4e363c3c7845 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.0 h1:tDWYNCJrpNnlNg8mVdlzAzPjl github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.0/go.mod h1:Uwb0d1GgxJieUWZG5WylTrgQ2SrldfjagAxheU8W6MQ= github.com/Chain-Zhang/pinyin v0.1.3 h1:RzErNyNwVa8z2sOLCuXSOtVdY/AsARb8mBzI2p2qtnE= github.com/Chain-Zhang/pinyin v0.1.3/go.mod h1:5iHpt9p4znrnaP59/hfPMnAojajkDxQaP9io+tRMPho= +github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= +github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akavel/rsrc v0.9.0 h1:HwUDC0+tMFWqN4D5G+o5siGD4oVsC3jn6zM8ocjc3nY= github.com/akavel/rsrc v0.9.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= diff --git a/src/action/generator.go b/src/action/generator.go index d0dac31d37348eb0b75fea594ff67feda079ff8f..7e146b075ae2e1a02237cd099ef724293380ce85 100644 --- a/src/action/generator.go +++ b/src/action/generator.go @@ -23,7 +23,7 @@ func Generate(defaultFile string, configFile string, fieldsToExportStr, format, fieldsToExport = strings.Split(fieldsToExportStr, ",") } - rows, colIsNumArr, err := gen.GenerateForOnTop(defaultFile, configFile, &fieldsToExport) + rows, colIsNumArr, err := gen.GenerateOnTopLevel(defaultFile, configFile, &fieldsToExport) if err != nil { return } diff --git a/src/gen/generator.go b/src/gen/generator.go index 6e8cea69d4fad7dc65d7d22a9cb868797c1bdcf0..e7f87a536185ef9595efd415c0b7f737dc0448eb 100644 --- a/src/gen/generator.go +++ b/src/gen/generator.go @@ -2,6 +2,7 @@ package gen import ( "errors" + "github.com/easysoft/zendata/src/gen/helper" "github.com/easysoft/zendata/src/model" commonUtils "github.com/easysoft/zendata/src/utils/common" constant "github.com/easysoft/zendata/src/utils/const" @@ -16,7 +17,7 @@ import ( "strings" ) -func GenerateForOnTop(defaultFile, configFile string, fieldsToExport *[]string, +func GenerateOnTopLevel(defaultFile, configFile string, fieldsToExport *[]string, ) (rows [][]string, colIsNumArr []bool, err error) { vari.DefaultDir = fileUtils.GetAbsDir(defaultFile) @@ -40,7 +41,7 @@ func GenerateForOnTop(defaultFile, configFile string, fieldsToExport *[]string, vari.Res = LoadResDef(*fieldsToExport) vari.ResLoading = false - topFieldNameToValuesMap := map[string][]string{} + topLevelFieldNameToValuesMap := map[string][]string{} // 为每个field生成值列表 for index, field := range vari.Def.Fields { @@ -55,7 +56,7 @@ func GenerateForOnTop(defaultFile, configFile string, fieldsToExport *[]string, vari.Def.Fields[index].Precision = field.Precision - topFieldNameToValuesMap[field.Field] = values + topLevelFieldNameToValuesMap[field.Field] = values colIsNumArr = append(colIsNumArr, field.IsNumb) } @@ -66,7 +67,11 @@ func GenerateForOnTop(defaultFile, configFile string, fieldsToExport *[]string, continue } - childValues := topFieldNameToValuesMap[child.Field] + childValues := topLevelFieldNameToValuesMap[child.Field] + if child.Value != "" { // is value expression + childValues = helper.GenExpressionValues(child, topLevelFieldNameToValuesMap) + } + arrOfArr = append(arrOfArr, childValues) } rows = putChildrenToArr(arrOfArr, vari.Recursive) diff --git a/src/gen/helper/expression.go b/src/gen/helper/expression.go new file mode 100644 index 0000000000000000000000000000000000000000..4434d5e4a732c28839423fd631cdc548c7832f68 --- /dev/null +++ b/src/gen/helper/expression.go @@ -0,0 +1,110 @@ +package helper + +import ( + "fmt" + "github.com/Knetic/govaluate" + "github.com/easysoft/zendata/src/model" + logUtils "github.com/easysoft/zendata/src/utils/log" + stringUtils "github.com/easysoft/zendata/src/utils/string" + "github.com/easysoft/zendata/src/utils/vari" + "github.com/mattn/go-runewidth" + "regexp" + "strconv" + "strings" +) + +func GenExpressionValues(field model.DefField, valuesMap map[string][]string) (ret []string) { + exp := field.Value + + reg := regexp.MustCompile(`\$([_,a-z,A-Z,0-9]+)`) + arr := reg.FindAllStringSubmatch(exp,-1) + + total := 1 + for _, items := range arr { // computer total + placeholder := items[0] + fieldName := items[1] + exp = strings.Replace(exp, placeholder, fieldName, 1) + + size := len(valuesMap[fieldName]) + if total < size { + total = size + } + } + + dataTypeFromValues := "int" + for i := 0; i < total; i++ { + params := make(map[string]interface{}) + + //expr1, err1 := govaluate.NewEvaluableExpression("1+1") + //result, err := expr1.Evaluate(params) + //fmt.Sprintf("%v, %v, %v", expr1, err1, result) + + for _, items := range arr { + fieldName := items[1] + referValues := valuesMap[fieldName] + referField := vari.TopFieldMap[fieldName] + + logUtils.PrintErrMsg(referField.Value) + + valStr := "N/A" + tp := "" + var val interface{} + if len(referValues) > 0 { + valStr = referValues[i % len(referValues)] + valStr = strings.TrimLeft(valStr, field.Prefix) + valStr = strings.TrimRight(valStr, field.Postfix) + + val, tp = getNumType(valStr) + if tp != "int" { + dataTypeFromValues = tp + } + } + params[fieldName] = val + } + + expr, err := govaluate.NewEvaluableExpression(exp) + if err != nil { + logUtils.PrintErrMsg(err.Error()) + ret = append(ret, "ERR") + } else { + result, err := expr.Evaluate(params) + if err != nil { + logUtils.PrintErrMsg(err.Error()) + } + + mask := "" + if dataTypeFromValues == "int" { + mask = "%.0f" + } else { + mask = "%d" + } + + str := fmt.Sprintf(field.Prefix + mask + field.Postfix, result) + if field.Length > runewidth.StringWidth(str) { + str = stringUtils.AddPad(str, field) + } + ret = append(ret, str) + } + } + + return +} + +func getNumType(str string) (val interface{}, tp string) { + val, errInt := strconv.ParseInt(str, 0, 64) + if errInt == nil { + tp = "int" + return + } + + val, errFloat := strconv.ParseFloat(str, 64) + if errFloat == nil { + tp = "float" + return + } + + val = str + tp = "float" + + return +} \ No newline at end of file diff --git a/src/gen/list.go b/src/gen/list.go index 1d9f849ad66f7198f580d6100f134f2f9392a62f..43abd256898a9ddb12831acf393e608570135e74 100644 --- a/src/gen/list.go +++ b/src/gen/list.go @@ -257,7 +257,7 @@ func CreateValuesFromYaml(field *model.DefField, yamlFile, stepStr string, repea configFile := vari.ConfigDir + yamlFile fieldsToExport := make([]string, 0) // set to empty to use all fields - rows, colIsNumArr, _ := GenerateForOnTop("", configFile, &fieldsToExport) + rows, colIsNumArr, _ := GenerateOnTopLevel("", configFile, &fieldsToExport) if field.Rand { rows = randomValuesArr(rows) }