提交 16b4177d 编写于 作者: fantasy_cs's avatar fantasy_cs

feat: Support for key range of prefix/suffix

上级 e329ceb3
/log/
/.idea/
/.vscode/
/build/
/tmp/cache/.data.db-shm
/tmp/cache/.data.db-wal
......
# 字段前后缀可以使用简单的区间功能,如 A-Z, 1-9,支持多片段,也支持随机或步长。对于引用文件的复杂方式不支持,这种情况建议使用多字段组合实现
fields:
- field: nesting # 这种简单的两个字段组合,可以改为前缀的方式实现。
fields:
- field: child1
range: 1-3
- field: child
range: A-E
postfix: ___
- field: range_n_m # 前后缀支持区间
prefix: 1-3
range: A-E
postfix: ___
- field: range_mul # 区间多片段
prefix: 1-2, a-d
range: A-E
postfix: ___
- field: step # 区间步长
prefix: 1-6:2
range: A-E
postfix: ___
- field: random # 区间随机
prefix: 1-3:R
range: A-E # 此处使用反引号,生成字符串"1-9"和"a-z"。注意:需要用[]符号扩起,否则不是合法的YAML文件格式。
postfix: ___
\ No newline at end of file
......@@ -3,6 +3,11 @@ package gen
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"time"
"github.com/easysoft/zendata/src/gen/helper"
"github.com/easysoft/zendata/src/model"
commonUtils "github.com/easysoft/zendata/src/utils/common"
......@@ -14,10 +19,6 @@ import (
"github.com/easysoft/zendata/src/utils/vari"
"github.com/fatih/color"
"github.com/mattn/go-runewidth"
"regexp"
"strconv"
"strings"
"time"
)
func GenerateFromContent(fileContents [][]byte, fieldsToExport *[]string) (
......@@ -135,6 +136,9 @@ func GenerateFromYaml(files []string, fieldsToExport *[]string) (
}
func GenerateForFieldRecursive(field *model.DefField, withFix bool) (values []string) {
field.PrefixRange = CreateFieldFixValuesFromList(field.Prefix, field)
field.PostfixRange = CreateFieldFixValuesFromList(field.Postfix, field)
if len(field.Fields) > 0 { // has sub fields
fieldNameToValuesMap := map[string][]string{} // refer field name to values
fieldMap := map[string]model.DefField{}
......@@ -248,30 +252,41 @@ func GenerateValuesForField(field *model.DefField) []string {
computerLoop(field)
indexOfRow := 0
count := 0
uniqueTotal := len(fieldWithValues.Values)
if l := len(field.PostfixRange.Values); l > 0 {
uniqueTotal *= l
}
if l := len(field.PrefixRange.Values); l > 0 {
uniqueTotal *= l
}
for {
// 2. random replacement
isRandomAndLoopEnd := !vari.ResLoading && // ignore rand in resource
!(*field).ReferToAnotherYaml &&
(*field).IsRand && (*field).LoopIndex > (*field).LoopEnd
// isNotRandomAndValOver := !(*field).IsRand && indexOfRow >= len(fieldWithValues.Values)
if count >= vari.Total || count >= len(fieldWithValues.Values) || isRandomAndLoopEnd {
if count >= vari.Total || count >= uniqueTotal || isRandomAndLoopEnd {
for _, v := range fieldWithValues.Values {
str := fmt.Sprintf("%v", v)
str = addFix(str, field, true)
str = addFix(str, field, count, true)
values = append(values, str)
}
break
}
// 处理格式、前后缀、loop等
val := loopFieldValWithFix(field, fieldWithValues, &indexOfRow, true)
val := loopFieldValWithFix(field, fieldWithValues, &indexOfRow, count, true)
values = append(values, val)
count++
if count >= vari.Total || count >= len(fieldWithValues.Values) {
if count >= vari.Total || count >= uniqueTotal {
break
}
(*field).LoopIndex = (*field).LoopIndex + 1
if (*field).LoopIndex > (*field).LoopEnd {
(*field).LoopIndex = (*field).LoopStart
......@@ -349,7 +364,7 @@ func loopFieldValues(field *model.DefField, oldValues []string, total int, withF
count := 0
for {
// 处理格式、前后缀、loop等
str := loopFieldValWithFix(field, fieldValue, &indexOfRow, withFix)
str := loopFieldValWithFix(field, fieldValue, &indexOfRow, count, withFix)
values = append(values, str)
count++
......@@ -369,7 +384,7 @@ func loopFieldValues(field *model.DefField, oldValues []string, total int, withF
}
func loopFieldValWithFix(field *model.DefField, fieldValue model.FieldWithValues,
indexOfRow *int, withFix bool) (loopStr string) {
indexOfRow *int, count int, withFix bool) (loopStr string) {
for j := 0; j < (*field).LoopIndex; j++ {
if loopStr != "" {
......@@ -385,14 +400,14 @@ func loopFieldValWithFix(field *model.DefField, fieldValue model.FieldWithValues
*indexOfRow++
}
loopStr = addFix(loopStr, field, withFix)
loopStr = addFix(loopStr, field, count, withFix)
return
}
func addFix(str string, field *model.DefField, withFix bool) (ret string) {
prefix := field.Prefix
postfix := field.Postfix
func addFix(str string, field *model.DefField, count int, withFix bool) (ret string) {
prefix := GetStrValueFromRange(field.PrefixRange, count)
postfix := GetStrValueFromRange(field.PostfixRange, count)
divider := field.Divider
if field.Length > runewidth.StringWidth(str) {
......@@ -409,6 +424,62 @@ func addFix(str string, field *model.DefField, withFix bool) (ret string) {
return
}
func GetStrValueFromRange(rang *model.Range, index int) string {
if len(rang.Values) == 0 {
return ""
}
idx := index % len(rang.Values)
x := rang.Values[idx]
return convPrefixVal2Str(x, "")
}
func convPrefixVal2Str(val interface{}, format string) string {
str := "n/a"
success := false
switch val.(type) {
case int64:
if format != "" {
str, success = stringUtils.FormatStr(format, val.(int64), 0)
}
if !success {
str = strconv.FormatInt(val.(int64), 10)
}
case float64:
precision := 0
if format != "" {
str, success = stringUtils.FormatStr(format, val.(float64), precision)
}
if !success {
str = strconv.FormatFloat(val.(float64), 'f', precision, 64)
}
case byte:
str = string(val.(byte))
if format != "" {
str, success = stringUtils.FormatStr(format, str, 0)
}
if !success {
str = string(val.(byte))
}
case string:
str = val.(string)
match, _ := regexp.MatchString("%[0-9]*d", format)
if match {
valInt, err := strconv.Atoi(str)
if err == nil {
str, success = stringUtils.FormatStr(format, valInt, 0)
}
} else {
str, success = stringUtils.FormatStr(format, str, 0)
}
default:
}
return str
}
func GenerateFieldVal(field model.DefField, fieldValue model.FieldWithValues, index *int) (val string, err error) {
// 叶节点
if len(fieldValue.Values) == 0 {
......
package gen
import (
"math"
"strconv"
"strings"
"github.com/easysoft/zendata/src/model"
commonUtils "github.com/easysoft/zendata/src/utils/common"
constant "github.com/easysoft/zendata/src/utils/const"
fileUtils "github.com/easysoft/zendata/src/utils/file"
"github.com/easysoft/zendata/src/utils/vari"
"math"
"strconv"
"strings"
)
func CreateListField(field *model.DefField, fieldWithValue *model.FieldWithValues) {
......@@ -84,6 +85,52 @@ func CreateFieldValuesFromList(field *model.DefField, fieldValue *model.FieldWit
}
}
func CreateFieldFixValuesFromList(strRang string, field *model.DefField) (rang *model.Range) {
rang = &model.Range{}
if strRang == "" {
return
}
rangeSections := ParseRangeProperty(strRang) // parse 1
index := 0
for _, rangeSection := range rangeSections {
if index >= constant.MaxNumb {
break
}
if rangeSection == "" {
continue
}
descStr, stepStr, count, countTag := ParseRangeSection(rangeSection) // parse 2
if strings.ToLower(stepStr) == "r" {
rang.IsRand = true
}
typ, desc := ParseRangeSectionDesc(descStr) // parse 3
items := make([]interface{}, 0)
if typ == "literal" {
items = CreateValuesFromLiteral(field, desc, stepStr, count, countTag)
} else if typ == "interval" {
items = CreateValuesFromInterval(field, desc, stepStr, count, countTag)
} else if typ == "yaml" { // load from a yaml
items = CreateValuesFromYaml(field, desc, stepStr, count, countTag)
field.ReferToAnotherYaml = true
}
rang.Values = append(rang.Values, items...)
index = index + len(items)
}
if len(rang.Values) == 0 {
rang.Values = append(rang.Values, "N/A")
}
return
}
func CheckRangeType(startStr string, endStr string, stepStr string) (dataType string, step interface{}, precision int,
rand bool, count int) {
step = 1
......
......@@ -108,6 +108,15 @@ type FieldSimple struct {
LoopIndex int `yaml:"-"`
IsRand bool `yaml:"-"`
ReferToAnotherYaml bool `yaml:"-"`
PrefixRange *Range `yaml:"-"`
PostfixRange *Range `yaml:"-"`
}
// add by Leo [2022/04/27]
type Range struct {
Values []interface{}
IsRand bool
}
type FieldWithValues struct {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册