Skip to content

Commit

Permalink
feat(confgen): auto deduce whether the map key is unique (#96)
Browse files Browse the repository at this point in the history
* feat: auto deduce map key unique or not

* feat: ignore xml

* fix: unittest

* fix: unittest

* feat: add unittest

* feat: del invalid case

* feat: unittest check error code

* feat: cr

* feat: E2017 err info

* feat: add GetFieldTypeName API for debugging

* refactor: improve error message

* refactor: improve API name and comments

* fix: unittest

---------

Co-authored-by: wenchy <wenchy.zwz@gmail.com>
  • Loading branch information
Kybxd and wenchy authored May 14, 2024
1 parent f3733a9 commit 49ea8d7
Show file tree
Hide file tree
Showing 14 changed files with 1,482 additions and 339 deletions.
295 changes: 171 additions & 124 deletions internal/confgen/parser.go

Large diffs are not rendered by default.

449 changes: 449 additions & 0 deletions internal/confgen/parser_test.go

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions internal/confgen/prop/prop.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ import (
"google.golang.org/protobuf/reflect/protoreflect"
)

func CheckKeyUnique(prop *tableaupb.FieldProp, key string, existed bool) error {
func RequireUnique(prop *tableaupb.FieldProp) bool {
unique := prop != nil && prop.Unique
if unique && existed {
return xerrors.E2005(key)
}
return nil
return unique
}

func CheckInRange(prop *tableaupb.FieldProp, fd protoreflect.FieldDescriptor, value protoreflect.Value, present bool) error {
Expand Down
32 changes: 12 additions & 20 deletions internal/confgen/prop/prop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,36 @@ import (
"github.com/tableauio/tableau/proto/tableaupb"
)

func TestCheckKeyUnique(t *testing.T) {
func TestRequireUnique(t *testing.T) {
type args struct {
prop *tableaupb.FieldProp
key string
existed bool
prop *tableaupb.FieldProp
}
tests := []struct {
name string
args args
wantErr bool
name string
args args
want bool
}{
{
name: "unique",
name: "require unique",
args: args{
prop: &tableaupb.FieldProp{
Unique: true,
},
key: "100",
existed: false,
},
wantErr: false,
want: true,
},
{
name: "not unique",
name: "not require unique",
args: args{
prop: &tableaupb.FieldProp{
Unique: true,
},
key: "100",
existed: true,
prop: nil,
},
wantErr: true,
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := CheckKeyUnique(tt.args.prop, tt.args.key, tt.args.existed); (err != nil) != tt.wantErr {
t.Errorf("CheckKeyUnique() error = %v, wantErr %v", err, tt.wantErr)
if got := RequireUnique(tt.args.prop); got != tt.want {
t.Errorf("RequireUnique() = %v, want %v", got, tt.want)
}
})
}
Expand Down
134 changes: 69 additions & 65 deletions internal/localizer/i18n/config/ecode/en.yaml
Original file line number Diff line number Diff line change
@@ -1,91 +1,95 @@
# [0001, 0999]: common error
E0001:
desc: sheet not found in book
text: sheet "{{.SheetName}}" not found in book "{{.BookName}}"
desc: Sheet not found in book.
text: Sheet "{{.SheetName}}" not found in book "{{.BookName}}".
E0002:
desc: cannot unmarshal file content to given proto.Message
text: 'failed to unmarshal file "{{.Filename}}" to message "{{.MessageName}}": {{.Error}}'
help: check the file content format is correct
desc: Cannot unmarshal file content to given proto.Message.
text: 'Failed to unmarshal file "{{.Filename}}" to message "{{.MessageName}}": {{.Error}}.'
help: Check the file content format is correct.
# [1000, 1999]: protogen error
E1000:
desc: column name conflicts in name row
text: found same name "{{.Name}}" in both "{{.Position1}}" and "{{.Position2}}"
help: rename column name and keep sure it is unique in name row
desc: Column name conflicts in name row.
text: Found same name "{{.Name}}" in both "{{.Position1}}" and "{{.Position2}}".
help: Rename column name and keep sure it is unique in name row.
# [2000, 2999]: confgen error
E2000:
desc: integer overflow
text: '"{{.Value}}" is outside of range [{{.Min}},{{.Max}}] of type {{.Type}}'
help: check field value and make sure it in representable range
desc: Integer overflow.
text: 'Value "{{.Value}}" is outside of range [{{.Min}},{{.Max}}] of type {{.Type}}.'
help: Check field value and make sure it in representable range.
E2001:
desc: field prop "refer" not configured correctly
text: in configured refer "{{.Refer}}", message "{{.MessageName}}" not found
help: 'try using format with sheet alias: "SheetName(SheetAlias).ColumnName"'
desc: Field prop "refer" not configured correctly.
text: In configured refer "{{.Refer}}", message "{{.MessageName}}" is not found.
help: 'Try using format with sheet alias: "SheetName(SheetAlias).ColumnName".'
E2002:
desc: field value not in referred space
text: value "{{.Value}}" not in referred space "{{.Refer}}"
help: guarantee value "{{.Value}}" was configured in referred space "{{.Refer}}" ahead
desc: Field value not in referred space.
text: Value "{{.Value}}" not in referred space "{{.Refer}}".
help: Guarantee value "{{.Value}}" was configured in referred space "{{.Refer}}" ahead.
E2003:
desc: illegal sequence number
text: 'value "{{.Value}}" does not meet sequence requirement: "sequence:{{.Sequence}}"'
help: '"sequence:{{.Sequence}}" requires value starts from "{{.Sequence}}" and increases monotonically'
desc: Illegal sequence number.
text: 'Value "{{.Value}}" does not meet sequence requirement: "sequence:{{.Sequence}}".'
help: 'Prop "sequence:{{.Sequence}}" requires value starts from "{{.Sequence}}" and increases monotonically.'
E2004:
desc: value is out of range
text: 'value "{{.Value}}" is out of range [{{.Range}}]'
help: change value and make sure it's in range
desc: Value is out of range.
text: 'Value "{{.Value}}" is out of range [{{.Range}}].'
help: Change value and make sure it's in range.
E2005:
desc: map key not unique
text: map key "{{.Key}}" already exists
help: 'map key is configured as "unique:true"'
desc: Map key not unique.
text: Map key "{{.Key}}" already exists.
help: Fix duplicate keys and ensure map key is unique.
E2006:
desc: enum value not defined in enum type
text: enum value "{{.Value}}" not defined in enum "{{.EnumName}}"
help: add enum value "{{.Value}}" to enum "{{.EnumName}}" definition
desc: Enum value not defined in enum type.
text: Enum value "{{.Value}}" not defined in enum "{{.EnumName}}".
help: Add enum value "{{.Value}}" to enum "{{.EnumName}}" definition.
E2007:
desc: invalid datetime format
text: '"{{.Value}}" is invalid datetime format, {{.Error}}'
help: 'follow datetime format: "yyyy-MM-dd HH:mm:ss", e.g.: "2020-01-01 01:00:00"'
desc: Invalid datetime format.
text: '"{{.Value}}" is invalid datetime format, {{.Error}}.'
help: 'Follow datetime format: "yyyy-MM-dd HH:mm:ss", e.g.: "2020-01-01 01:00:00".'
E2008:
desc: invalid duration format
text: '"{{.Value}}" is invalid duration format, {{.Error}}'
help: 'follow duration format in the form "72h3m0.5s"'
desc: Invalid duration format.
text: '"{{.Value}}" is invalid duration format, {{.Error}}.'
help: 'Follow duration format in the form "72h3m0.5s".'
E2009:
desc: duplicate key exists in different sheets
text: 'field {{.FieldName}} has duplicate key "{{.Key}}"'
help: "key must not be duplicate when merge multiple sheets"
desc: Duplicate key exists in different sheets.
text: 'Field {{.FieldName}} has duplicate key "{{.Key}}".'
help: Key must not be duplicate when merge multiple sheets.
E2010:
desc: union type has no corresponding value field
text: 'union type "{{.TypeValue}}" has no corresponding value field with number "{{.FieldNumber}}"'
help: 'add new union value field and bind it to type "{{.TypeValue}}"'
desc: Union type has no corresponding value field.
text: 'Union type "{{.TypeValue}}" has no corresponding value field with number "{{.FieldNumber}}".'
help: 'Add new union value field and bind it to type "{{.TypeValue}}".'
E2011:
desc: field presence required but cell not filled
text: cell data is not filled explicitly
help: fill cell data explicitly
desc: Field presence required but cell not filled.
text: Cell data is not filled explicitly.
help: Fill cell data explicitly.
E2012:
desc: invalid syntax of numerical value
text: '"{{.Value}}" cannot be parsed to numerical type "{{.FieldType}}", {{.Error}}'
help: fill cell data with valid syntax of numerical type "{{.FieldType}}"
desc: Invalid syntax of numerical value.
text: '"{{.Value}}" cannot be parsed to numerical type "{{.FieldType}}", {{.Error}}.'
help: Fill cell data with valid syntax of numerical type "{{.FieldType}}".
E2013:
desc: invalid syntax of boolean value
text: '"{{.Value}}" cannot be parsed to boolean type, {{.Error}}'
help: "boolean value can be: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False"
desc: Invalid syntax of boolean value.
text: '"{{.Value}}" cannot be parsed to boolean type, {{.Error}}.'
help: "Boolean value can be: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False."
E2014:
desc: sheet column not found
text: sheet column "{{.Column}}" not found
help: add column "{{.Column}}"
desc: Sheet column not found.
text: Sheet column "{{.Column}}" not found.
help: Add column "{{.Column}}".
E2015:
desc: referred sheet column not found
text: referred sheet column "{{.Column}}" not found in workbook "{{.BookName}}", worksheet "{{.SheetName}}"
help: change "refer" prop or add referred sheet column "{{.Column}}"
desc: Referred sheet column not found.
text: Referred sheet column "{{.Column}}" not found in workbook "{{.BookName}}", worksheet "{{.SheetName}}".
help: Change "refer" prop or add referred sheet column "{{.Column}}".
E2016:
desc: list elements are not present continuously
text: The {{.FirstNonePresentIndex}}-th element is not present, but the subsequent {{.NextPresentIndex}}-th element is present
help: ensure all subsequent elements after the first none-present element are not present
desc: List elements are not present continuously.
text: The {{.FirstNonePresentIndex}}-th element is not present, but the subsequent {{.NextPresentIndex}}-th element is present.
help: Ensure all subsequent elements after the first none-present element are not present.
E2017:
desc: Map contains multiple empty keys.
text: '"{{.MapType}}" contains multiple empty keys.'
help: Ensure there is at most one empty key in map, or assign them explicitly if you need multiple zero-value keys.
# [3000, 3999]: importer error
E3000:
desc: no workbook file found about sheet specifier
text: no workbook file found in pattern "{{.Pattern}}" with sheet specifier "{{.SheetSpecifier}}"
help: guarantee sheet specifier in format "<BookNameGlob>[#SheetName]"
desc: No workbook file found about sheet specifier.
text: No workbook file found in pattern "{{.Pattern}}" with sheet specifier "{{.SheetSpecifier}}".
help: Guarantee sheet specifier in format "<BookNameGlob>[#SheetName]".
E3001:
desc: no worksheet found in workbook
text: worksheet "{{.SheetName}}" not found in workbook "{{.BookName}}"
help: add proper worksheet "{{.SheetName}}" to workbook "{{.BookName}}"
desc: No worksheet found in workbook.
text: Worksheet "{{.SheetName}}" not found in workbook "{{.BookName}}".
help: Add proper worksheet "{{.SheetName}}" to workbook "{{.BookName}}".
134 changes: 69 additions & 65 deletions internal/localizer/i18n/config/ecode/zh.yaml
Original file line number Diff line number Diff line change
@@ -1,91 +1,95 @@
# [0001, 0999]: common error
E0001:
desc: sheet not found in book
text: 工作表 "{{.SheetName}}" 在工作簿 "{{.BookName}}" 中未找到
desc: Sheet not found in book.
text: 工作表 "{{.SheetName}}" 在工作簿 "{{.BookName}}" 中未找到
E0002:
desc: cannot unmarshal file content to given proto.Message
text: '无法将"{{.Filename}}"的文件内容反序列化到Protobuf消息"{{.MessageName}}": {{.Error}}'
help: 检查文件内容格式是否正确
desc: Cannot unmarshal file content to given proto.Message.
text: '无法将"{{.Filename}}"的文件内容反序列化到Protobuf消息"{{.MessageName}}": {{.Error}}'
help: 检查文件内容格式是否正确
# [1000, 1999]: protogen error
E1000:
desc: column name conflicts in name row
text: '"{{.Position1}}" 和 "{{.Position2}}" 存在相同的列名 "{{.Name}}"'
help: 修改冲突的列名,以确保唯一性
desc: Column name conflicts in name row.
text: '"{{.Position1}}" 和 "{{.Position2}}" 存在相同的列名 "{{.Name}}"'
help: 修改冲突的列名,以确保唯一性
# [2000, 2999]: confgen error
E2000:
desc: integer overflow
text: '整数 "{{.Value}}" 溢出,不在类型 {{.Type}} 的值域范围:[{{.Min}},{{.Max}}]'
help: 请检查配置的整数,确保不要溢出
desc: Integer overflow.
text: '整数 "{{.Value}}" 溢出,不在类型 {{.Type}} 的值域范围:[{{.Min}},{{.Max}}]'
help: 请检查配置的整数,确保不要溢出
E2001:
desc: field prop "refer" not configured correctly
text: 解析refer值空间校验 "{{.Refer}}" 时,找不到对应工作表 "{{.MessageName}}"
help: '尝试加上sheet别名, 格式: "SheetName(SheetAlias).ColumnName"'
desc: Field prop "refer" not configured correctly.
text: 解析refer值空间校验 "{{.Refer}}" 时,找不到对应工作表 "{{.MessageName}}"
help: '尝试加上sheet别名, 格式: "SheetName(SheetAlias).ColumnName"'
E2002:
desc: field value not in referred space
text: 值 "{{.Value}}" 不在 "{{.Refer}}" 所指定的值空间中
help: 请确保在 "{{.Refer}}" 所指定的值空间中提前配置好值 "{{.Value}}"
desc: Field value not in referred space.
text: 值 "{{.Value}}" 不在 "{{.Refer}}" 所指定的值空间中
help: 请确保在 "{{.Refer}}" 所指定的值空间中提前配置好值 "{{.Value}}"
E2003:
desc: illegal sequence number
text: '值 "{{.Value}}" 不符合序列 "sequence:{{.Sequence}}" 要求'
help: '序列 "sequence:{{.Sequence}}" 要求值从 "{{.Sequence}}" 开始单调递增'
desc: Illegal sequence number.
text: '值 "{{.Value}}" 不符合序列 "sequence:{{.Sequence}}" 要求'
help: '序列 "sequence:{{.Sequence}}" 要求值从 "{{.Sequence}}" 开始单调递增'
E2004:
desc: value is out of range
text: '值 "{{.Value}}" 超出限制的区间 [{{.Range}}]'
help: 修改值使其在限制的区间内
desc: Value is out of range.
text: '值 "{{.Value}}" 超出限制的区间 [{{.Range}}]'
help: 修改值使其在限制的区间内
E2005:
desc: map key not unique
text: map的key "{{.Key}}" 已存在
help: 'map的key已被配置为唯一 "unique:true", 不允许重复配置相同的key值'
desc: Map key not unique.
text: Map的key "{{.Key}}" 已存在
help: 此处map的key要保证唯一性, 不允许重复配置相同key。
E2006:
desc: enum value not defined in enum type
text: enum 值 "{{.Value}}" 未在 enum 类型 "{{.EnumName}}" 中定义
help: 将 enum 值 "{{.Value}}" 添加到 enum 类型 "{{.EnumName}}" 定义中
desc: Enum value not defined in enum type.
text: Enum 值 "{{.Value}}" 未在 enum 类型 "{{.EnumName}}" 中定义
help: 将 enum 值 "{{.Value}}" 添加到 enum 类型 "{{.EnumName}}" 定义中
E2007:
desc: invalid datetime format
text: '"{{.Value}}" 是无效的日期时间(datetime)格式, {{.Error}}'
help: '请遵循日期时间(datetime)格式: "yyyy-MM-dd HH:mm:ss", 示例: "2020-01-01 01:00:00"'
desc: Invalid datetime format.
text: '"{{.Value}}" 是无效的日期时间(datetime)格式, {{.Error}}'
help: '请遵循日期时间(datetime)格式: "yyyy-MM-dd HH:mm:ss", 示例: "2020-01-01 01:00:00"'
E2008:
desc: invalid duration format
text: '"{{.Value}}" 是无效的时间段(duration)格式, {{.Error}}'
help: '请遵循时间段(duration)格式,以 "72h3m0.5s" 形式来配置'
desc: Invalid duration format.
text: '"{{.Value}}" 是无效的时间段(duration)格式, {{.Error}}'
help: '请遵循时间段(duration)格式,以 "72h3m0.5s" 形式来配置'
E2009:
desc: duplicate key exists in different sheets
text: '字段 {{.FieldName}} 在配置表合表时,存在重复的键 "{{.Key}}"'
help: "合表时,不同的表不允许配置重复的键"
desc: Duplicate key exists in different sheets.
text: '字段 {{.FieldName}} 在配置表合表时,存在重复的键 "{{.Key}}"'
help: "合表时,不同的表不允许配置重复的键"
E2010:
desc: union type has no corresponding value field
text: 'union 类型"{{.TypeValue}}"找不到 field number 为"{{.FieldNumber}}"的对应 value 字段'
help: '新增 union value field 并绑定到类型"{{.TypeValue}}"'
desc: Union type has no corresponding value field.
text: 'Union 类型"{{.TypeValue}}"找不到 field number 为"{{.FieldNumber}}"的对应 value 字段'
help: '新增 union value field 并绑定到类型"{{.TypeValue}}"'
E2011:
desc: field presence required but cell not filled
text: 单元格数据未被显式填充
help: 请显式填充单元格数据
desc: Field presence required but cell not filled.
text: 单元格数据未被显式填充
help: 请显式填充单元格数据
E2012:
desc: invalid syntax of numerical value
text: 无法将 "{{.Value}}" 解析为数值类型 "{{.FieldType}}", {{.Error}}
help: '请依据类型 "{{.FieldType}}" 填充合法的数值; int32/int64: 32/64位整数, uint32/uint64: 32/64位正整数, float32/float64: 32/64位浮点数'
desc: Invalid syntax of numerical value.
text: 无法将 "{{.Value}}" 解析为数值类型 "{{.FieldType}}", {{.Error}}
help: '请依据类型 "{{.FieldType}}" 填充合法的数值; int32/int64: 32/64位整数, uint32/uint64: 32/64位正整数, float32/float64: 32/64位浮点数'
E2013:
desc: invalid syntax of boolean value
text: 无法将 "{{.Value}}" 解析为布尔类型, {{.Error}}
help: "布尔值可以为: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False"
desc: Invalid syntax of boolean value.
text: 无法将 "{{.Value}}" 解析为布尔类型, {{.Error}}
help: "布尔值可以为: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False"
E2014:
desc: sheet column not found
text: 未找到工作表的列 "{{.Column}}"
help: 新增工作表的列 "{{.Column}}"
desc: Sheet column not found.
text: 未找到工作表的列 "{{.Column}}"
help: 新增工作表的列 "{{.Column}}"
E2015:
desc: referred sheet column not found
text: 在工作簿 "{{.BookName}}" 的工作表 "{{.SheetName}}" 中未找到外键对应的列 "{{.Column}}"
help: 修改字段属性 "refer", 或新增外键的列 "{{.Column}}"
desc: Referred sheet column not found.
text: 在工作簿 "{{.BookName}}" 的工作表 "{{.SheetName}}" 中未找到外键对应的列 "{{.Column}}"
help: 修改字段属性 "refer", 或新增外键的列 "{{.Column}}"
E2016:
desc: list elements are not present continuously
text: 数组第{{.FirstNonePresentIndex}}个元素为空, 但后续第{{.NextPresentIndex}}个元素却非空
help: 请确保数组出现首个空元素时, 后续所有元素都为空
desc: List elements are not present continuously.
text: 数组第{{.FirstNonePresentIndex}}个元素为空, 但后续第{{.NextPresentIndex}}个元素却非空。
help: 请确保数组出现首个空元素时, 后续所有元素都为空。
E2017:
desc: Map contains multiple empty keys.
text: '"{{.MapType}}" 存在多个空值key。'
help: 请确保map中最多仅有一个空值key,如果确实需要多个key为零值,请显式填充。
# [3000, 3999]: importer error
E3000:
desc: no workbook file found about sheet specifier
text: 解析工作表指示器 "{{.SheetSpecifier}}" 时, 模式 "{{.Pattern}}" 找不到工作簿文件
help: 确保工作表指示器格式输入合法 "<BookNameGlob>[#SheetName]"
desc: No workbook file found about sheet specifier.
text: 解析工作表指示器 "{{.SheetSpecifier}}" 时, 模式 "{{.Pattern}}" 找不到工作簿文件
help: 确保工作表指示器格式输入合法 "<BookNameGlob>[#SheetName]"
E3001:
desc: no worksheet found in workbook
text: 工作簿 "{{.BookName}}" 中不存在工作表 "{{.SheetName}}"
help: 将合适的工作表 "{{.SheetName}}" 添加到工作簿 "{{.BookName}}"
desc: No worksheet found in workbook.
text: 工作簿 "{{.BookName}}" 中不存在工作表 "{{.SheetName}}"
help: 将合适的工作表 "{{.SheetName}}" 添加到工作簿 "{{.BookName}}"
Loading

0 comments on commit 49ea8d7

Please sign in to comment.