Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
feat: chinese name and fix slice tag bug AND add(#141)
Browse files Browse the repository at this point in the history
* fix slice len and slice_len

* stop min

* fix len test

* add chinese name

* add chinese name

* Set tag priority

* fix test fun

* fix golangci-lint error

* fix golint and test error

* fix golangci-lint error

* Fix merge redundant code

* fix faker test

Co-authored-by: Iman Tumorang <iman.tumorang@gmail.com>
  • Loading branch information
qiangmzsx and bxcodec committed Jan 31, 2022
1 parent df4deac commit cabb112
Show file tree
Hide file tree
Showing 4 changed files with 232 additions and 9 deletions.
47 changes: 44 additions & 3 deletions faker.go
Expand Up @@ -102,6 +102,9 @@ const (
FirstNameFemaleTag = "first_name_female"
LastNameTag = "last_name"
NAME = "name"
ChineseFirstNameTag = "chinese_first_name"
ChineseLastNameTag = "chinese_last_name"
ChineseNameTag = "chinese_name"
GENDER = "gender"
UnixTimeTag = "unix_time"
DATE = "date"
Expand Down Expand Up @@ -134,6 +137,15 @@ const (
//hyphen = "-"
)

// PriorityTags define the priority order of the tag
var PriorityTags = []string{ID, HyphenatedID, EmailTag, MacAddressTag, DomainNameTag, UserNameTag, URLTag, IPV4Tag,
IPV6Tag, PASSWORD, JWT, LATITUDE, LONGITUDE, CreditCardNumber, CreditCardType, PhoneNumber, TollFreeNumber,
E164PhoneNumberTag, TitleMaleTag, TitleFemaleTag, FirstNameTag, FirstNameMaleTag, FirstNameFemaleTag, LastNameTag,
NAME, ChineseFirstNameTag, ChineseLastNameTag, ChineseNameTag, GENDER, UnixTimeTag, DATE, TIME, MonthNameTag,
YEAR, DayOfWeekTag, DayOfMonthTag, TIMESTAMP, CENTURY, TIMEZONE, TimePeriodTag, WORD, SENTENCE, PARAGRAPH,
CurrencyTag, AmountTag, AmountWithCurrencyTag, SKIP, Length, SliceLength, Language, BoundaryStart, BoundaryEnd, ONEOF,
}

var defaultTag = map[string]string{
EmailTag: EmailTag,
MacAddressTag: MacAddressTag,
Expand All @@ -158,6 +170,9 @@ var defaultTag = map[string]string{
FirstNameFemaleTag: FirstNameFemaleTag,
LastNameTag: LastNameTag,
NAME: NAME,
ChineseFirstNameTag: ChineseFirstNameTag,
ChineseLastNameTag: ChineseLastNameTag,
ChineseNameTag: ChineseNameTag,
GENDER: GENDER,
UnixTimeTag: UnixTimeTag,
DATE: DATE,
Expand Down Expand Up @@ -208,6 +223,9 @@ var mapperTag = map[string]TaggedFunction{
FirstNameFemaleTag: GetPerson().FirstNameFemale,
LastNameTag: GetPerson().LastName,
NAME: GetPerson().Name,
ChineseFirstNameTag: GetPerson().ChineseFirstName,
ChineseLastNameTag: GetPerson().ChineseLastName,
ChineseNameTag: GetPerson().ChineseName,
GENDER: GetPerson().Gender,
UnixTimeTag: GetDateTimer().UnixTime,
DATE: GetDateTimer().Date,
Expand Down Expand Up @@ -422,7 +440,7 @@ func AddProvider(tag string, provider TaggedFunction) error {
if _, ok := mapperTag[tag]; ok {
return errors.New(ErrTagAlreadyExists)
}

PriorityTags = append(PriorityTags, tag)
mapperTag[tag] = provider

return nil
Expand Down Expand Up @@ -640,11 +658,13 @@ func isZero(field reflect.Value) (bool, error) {
}

func decodeTags(typ reflect.Type, i int) structTag {
tags := strings.Split(typ.Field(i).Tag.Get(tagName), ",")
tagField := typ.Field(i).Tag.Get(tagName)
tags := strings.Split(tagField, ",")

keepOriginal := false
uni := false
res := make([]string, 0)
pMap := make(map[string]string)
for _, tag := range tags {
if tag == keep {
keepOriginal = true
Expand All @@ -653,7 +673,28 @@ func decodeTags(typ reflect.Type, i int) structTag {
uni = true
continue
}
res = append(res, tag)
// res = append(res, tag)
ptag := strings.ToLower(strings.Trim(strings.Split(tag, "=")[0], " "))
pMap[ptag] = tag
ptag = strings.ToLower(strings.Trim(strings.Split(tag, ":")[0], " "))
pMap[ptag] = tag
}
// Priority
for _, ptag := range PriorityTags {
if tag, ok := pMap[ptag]; ok {
if ptag == ONEOF {
res = append(res, tags...)
} else {
res = append(res, tag)
}
delete(pMap, ptag)
}
}
// custom,keep,unique
if len(res) < 1 {
if !keepOriginal && !uni {
res = append(res, tags...)
}
}

return structTag{
Expand Down
55 changes: 49 additions & 6 deletions faker_test.go
Expand Up @@ -33,6 +33,34 @@ var (
sliceLenIncorrectTags = [3]string{"slice_len=b", "slice_len=-1", "slice_len=-10"}
)

type Coupon struct {
ID int `json:"id" xorm:"id"`
BrokerCode string `json:"broker_code" xorm:"broker_code"`
IgetUID int `json:"iget_uid" xorm:"iget_uid"`
CreateTime string `json:"create_time" xorm:"create_time"`
CFirstName string `json:"chinese_first_name" faker:"chinese_first_name"`
CLsstName string `json:"chinese_last_name" faker:"chinese_last_name"`
CName string `json:"name" faker:"chinese_name"`
AdNames []string `json:"ad_name" xorm:"ad_name" faker:"slice_len=5,len=10"` // faker:"len=10,slice_len=5"
CdNames []string `json:"cd_name" xorm:"cd_name" faker:"len=10,slice_len=5"` //
}

func TestPLen(t *testing.T) {
coupon := Coupon{}
err := FakeData(&coupon)
if err != nil {
t.Fatal(err)
return
}
if len(coupon.AdNames[0]) != 10 || len(coupon.AdNames) != 5 {
t.Fatal("slice len is error")
}
if len(coupon.CdNames[0]) != 10 || len(coupon.CdNames) != 5 {
t.Fatal("slice len is error")
}
t.Logf("%+v\n", coupon)
}

type SomeInt32 int32

type TArray [16]byte
Expand Down Expand Up @@ -224,6 +252,9 @@ type TaggedStruct struct {
FirstNameFemale string `faker:"first_name_female"`
LastName string `faker:"last_name"`
Name string `faker:"name"`
ChineseFirstName string `faker:"chinese_first_name"`
ChineseLastName string `faker:"chinese_last_name"`
ChineseName string `faker:"chinese_name"`
UnixTime int64 `faker:"unix_time"`
Date string `faker:"date"`
Time string `faker:"time"`
Expand Down Expand Up @@ -394,19 +425,28 @@ func TestSetDataIfArgumentNotHaveReflect(t *testing.T) {

func TestSetDataErrorDataParseTagStringType(t *testing.T) {
temp := &struct {
Test string `faker:"test"`
Test string `faker:"test_no_exist"`
}{}
fmt.Printf("%+v ", temp)
for idx, tag := range PriorityTags {
if tag == "test_no_exist" {
PriorityTags[idx] = ""
}
}
if err := FakeData(temp); err == nil {
t.Error("Exptected error Unsupported tag, but got nil")
t.Error("Exptected error Unsupported tag, but got nil", temp, err)
}

}

func TestSetDataErrorDataParseTagIntType(t *testing.T) {
temp := &struct {
Test int `faker:"test"`
Test int `faker:"test_no_exist"`
}{}

for idx, tag := range PriorityTags {
if tag == "test_no_exist" {
PriorityTags[idx] = ""
}
}
if err := FakeData(temp); err == nil {
t.Error("Expected error Unsupported tag, but got nil")
}
Expand Down Expand Up @@ -1672,6 +1712,7 @@ func TestOneOfTag__BadInputsForFloats(t *testing.T) {
err := FakeData(&a)
if err == nil {
t.Errorf("expected error, but got no error")
return
}
actual := err.Error()
expected := ErrNotEnoughTagArguments
Expand Down Expand Up @@ -1705,7 +1746,7 @@ func TestOneOfTag__BadInputsForFloats(t *testing.T) {
a := CustomWrongFloat9{}
err := FakeData(&a)
if err == nil {
t.Fatal("expected error, but got no error")
t.Fatal("expected error, but got no error", err)
}
actual := err.Error()
expected := ErrUnsupportedTagArguments
Expand Down Expand Up @@ -1809,11 +1850,13 @@ func TestOneOfTag__BadInputsForInts(t *testing.T) {

type CustomTypeInt64Wrong struct {
Age int64 `faker:"oneof: 1_000_000, oops"`
Avg int64 `faker:"boundary_start=31, boundary_end=88"`
}

t.Run("should error for int64 with bad tag arguments", func(t *testing.T) {
a := CustomTypeInt64Wrong{}
err := FakeData(&a)
t.Log(a.Age, a.Avg)
if err == nil {
t.Errorf("expected error but got nil")
}
Expand Down
108 changes: 108 additions & 0 deletions person.go
Expand Up @@ -15,6 +15,9 @@ type Dowser interface {
LastName(v reflect.Value) (interface{}, error)
Name(v reflect.Value) (interface{}, error)
Gender(v reflect.Value) (interface{}, error)
ChineseFirstName(v reflect.Value) (interface{}, error)
ChineseLastName(v reflect.Value) (interface{}, error)
ChineseName(v reflect.Value) (interface{}, error)
}

var person Dowser
Expand Down Expand Up @@ -111,6 +114,60 @@ var randNameFlag int

var genders = []string{"Male", "Female", "Prefer to skip"}

var chineseFirstNames = []string{
"赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许",
"何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章",
"云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳",
"酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
"乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹",
"姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧", "计", "伏", "成", "戴", "谈", "宋", "茅", "庞",
"熊", "纪", "舒", "屈", "项", "祝", "董", "梁", "杜", "阮", "蓝", "闵", "席", "季", "麻", "强", "贾", "路", "娄", "危",
"江", "童", "颜", "郭", "梅", "盛", "林", "刁", "钟", "徐", "邱", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍",
"虞", "万", "支", "柯", "昝", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗", "丁", "宣", "贲", "邓",
"郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚", "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁",
"荀", "羊", "於", "惠", "甄", "麴", "家", "封", "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫",
"乌", "焦", "巴", "弓", "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫",
"宁", "仇", "栾", "暴", "甘", "钭", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙", "叶", "幸", "司", "韶",
"郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂", "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙",
"池", "乔", "阴", "郁", "胥", "能", "苍", "双", "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵",
"冉", "宰", "郦", "雍", "舄", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农",
"温", "别", "庄", "晏", "柴", "瞿", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容", "向", "古", "易", "慎",
"戈", "廖", "庾", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘", "匡", "国", "文", "寇", "广", "禄", "阙", "东",
"殴", "殳", "沃", "利", "蔚", "越", "夔", "隆", "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚",
"那", "简", "饶", "空", "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "後", "荆", "红",
"游", "竺", "权", "逯", "盖", "益", "桓", "公", "司马", "上官", "欧阳", "夏侯", "诸葛",
}

var chineseLastNames = []string{
"澄邈", "德泽", "海超", "海阳", "海荣", "海逸", "海昌", "瀚钰", "瀚文", "涵亮", "涵煦", "明宇",
"涵衍", "浩皛", "浩波", "浩博", "浩初", "浩宕", "浩歌", "浩广", "浩邈", "浩气", "浩思", "浩言",
"鸿宝", "鸿波", "鸿博", "鸿才", "鸿畅", "鸿畴", "鸿达", "鸿德", "鸿飞", "鸿风", "鸿福", "鸿光",
"鸿晖", "鸿朗", "鸿文", "鸿轩", "鸿煊", "鸿骞", "鸿远", "鸿云", "鸿哲", "鸿祯", "鸿志", "鸿卓",
"嘉澍", "光济", "澎湃", "彭泽", "鹏池", "鹏海", "浦和", "浦泽", "瑞渊", "越泽", "博耘", "德运",
"辰宇", "辰皓", "辰钊", "辰铭", "辰锟", "辰阳", "辰韦", "辰良", "辰沛", "晨轩", "晨涛", "晨濡",
"晨潍", "鸿振", "吉星", "铭晨", "起运", "运凡", "运凯", "运鹏", "运浩", "运诚", "运良", "运鸿",
"运锋", "运盛", "运升", "运杰", "运珧", "运骏", "运凯", "运乾", "维运", "运晟", "运莱", "运华",
"耘豪", "星爵", "星腾", "星睿", "星泽", "星鹏", "星然", "震轩", "震博", "康震", "震博", "振强",
"振博", "振华", "振锐", "振凯", "振海", "振国", "振平", "昂然", "昂雄", "昂杰", "昂熙", "昌勋",
"昌盛", "昌淼", "昌茂", "昌黎", "昌燎", "昌翰", "晨朗", "德明", "德昌", "德曜", "范明", "飞昂",
"高旻", "晗日", "昊然", "昊天", "昊苍", "昊英", "昊宇", "昊嘉", "昊明", "昊伟", "昊硕", "昊磊",
"昊东", "鸿晖", "鸿朗", "华晖", "金鹏", "晋鹏", "敬曦", "景明", "景天", "景浩", "俊晖", "君昊",
"昆锐", "昆卉", "昆峰", "昆颉", "昆谊", "昆皓", "昆鹏", "昆明", "昆杰", "昆雄", "昆纶", "鹏涛",
"依秋", "依波", "香巧", "紫萱", "涵易", "忆之", "幻巧", "美倩", "安寒", "白亦", "惜玉", "碧春",
"怜雪", "听南", "念蕾", "紫夏", "凌旋", "芷梦", "凌寒", "梦竹", "千凡", "丹蓉", "慧贞", "思菱",
"平卉", "笑柳", "雪卉", "南蓉", "谷梦", "巧兰", "绿蝶", "飞荷", "佳蕊", "芷荷", "怀瑶", "慕易",
"若芹", "紫安", "曼冬", "寻巧", "雅昕", "尔槐", "以旋", "初夏", "依丝", "怜南", "傲菡", "谷蕊",
"笑槐", "飞兰", "笑卉", "迎荷", "佳音", "梦君", "妙绿", "觅雪", "寒安", "沛凝", "白容", "乐蓉",
"映安", "依云", "映冬", "凡雁", "梦秋", "梦凡", "秋巧", "若云", "元容", "怀蕾", "灵寒", "天薇",
"翠安", "乐琴", "宛南", "怀蕊", "白风", "访波", "亦凝", "易绿", "夜南", "曼凡", "亦巧", "青易",
"冰真", "白萱", "友安", "海之", "小蕊", "又琴", "天风", "若松", "盼菡", "秋荷", "香彤", "语梦",
"惜蕊", "迎彤", "沛白", "雁彬", "易蓉", "雪晴", "诗珊", "春冬", "晴钰", "冰绿", "半梅", "笑容",
"沛凝", "映秋", "盼烟", "晓凡", "涵雁", "问凝", "冬萱", "晓山", "雁蓉", "梦蕊", "山菡", "南莲",
"飞双", "凝丝", "思萱", "怀梦", "雨梅", "冷霜", "向松", "迎丝", "迎梅", "雅彤", "香薇", "以山",
"碧萱", "寒云", "向南", "书雁", "怀薇", "思菱", "忆文", "翠巧", "书文", "若山", "向秋", "凡白",
"绮烟", "从蕾", "天曼", "又亦", "从语", "绮彤", "之玉", "凡梅", "依琴", "沛槐", "又槐", "元绿",
}

// GetPerson returns a new Dowser interface of Person struct
func GetPerson() Dowser {
mu.Lock()
Expand Down Expand Up @@ -269,3 +326,54 @@ func Gender() string {
return p.gender()
}).(string)
}

// ChineseFirstName returns a random chinese first name
func (p Person) ChineseFirstName(v reflect.Value) (interface{}, error) {
return p.chineseFirstName(), nil
}

func (p Person) chineseFirstName() string {
return randomElementFromSliceString(chineseFirstNames)
}

// ChineseFirstName get chinese first name
func ChineseFirstName() string {
return singleFakeData(ChineseFirstNameTag, func() interface{} {
p := Person{}
return p.chineseFirstName()
}).(string)
}

// ChineseLastName returns a random chinese last name
func (p Person) ChineseLastName(v reflect.Value) (interface{}, error) {
return p.chineseLastName(), nil
}

func (p Person) chineseLastName() string {
return randomElementFromSliceString(chineseLastNames)
}

// ChineseLastName get chinese lsst name
func ChineseLastName() string {
return singleFakeData(ChineseLastNameTag, func() interface{} {
p := Person{}
return p.chineseLastName()
}).(string)
}

// ChineseName returns a random nhinese name
func (p Person) ChineseName(v reflect.Value) (interface{}, error) {
return p.chineseName(), nil
}

func (p Person) chineseName() string {
return fmt.Sprintf("%s%s", randomElementFromSliceString(chineseFirstNames), randomElementFromSliceString(chineseLastNames))
}

// ChineseName get chinese lsst name
func ChineseName() string {
return singleFakeData(ChineseNameTag, func() interface{} {
p := Person{}
return p.chineseName()
}).(string)
}
31 changes: 31 additions & 0 deletions person_test.go
Expand Up @@ -147,6 +147,7 @@ func TestFakeNameFemale(t *testing.T) {
if name == "" {
t.Error("Expected from function name string get empty string")
}
t.Log(name)
}

func TestFakeGender(t *testing.T) {
Expand All @@ -165,3 +166,33 @@ func TestFakeGenderPublicFunction(t *testing.T) {
t.Error("Expected value from variable genders in function Gender")
}
}

func TestChineseFirstName(t *testing.T) {
firstname, err := GetPerson().ChineseFirstName(reflect.Value{})
if err != nil {
t.Error("Expected not error, got err", err)
}
t.Log(firstname)
if !slice.Contains(chineseFirstNames, firstname.(string)) {
t.Error("Expected value from either chineseFirstNames in function ChineseFirstName")
}
}

func TestChineseLastName(t *testing.T) {
firstname, err := GetPerson().ChineseLastName(reflect.Value{})
if err != nil {
t.Error("Expected not error, got err", err)
}
t.Log(firstname)
if !slice.Contains(chineseLastNames, firstname.(string)) {
t.Error("Expected value from either chineseLastNames in function ChineseLastName")
}
}

func TestChineseName(t *testing.T) {
firstname, err := GetPerson().ChineseName(reflect.Value{})
if err != nil {
t.Error("Expected not error, got err", err)
}
t.Log(firstname)
}

0 comments on commit cabb112

Please sign in to comment.