diff --git a/README.md b/README.md index 9eba3f3..6fc5e52 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ See documentation in [Godoc](https://godoc.org/github.com/bxcodec/faker) ```shell go get -u github.com/bxcodec/faker ``` -## Example +# Example -### With Tag +## With Tag Supported tag: **Internet :** @@ -213,7 +213,52 @@ func main() { ``` -### Without Tag +## Custom Generator Provider +You can also add your own generator function to your own defined tags. See example below +```go +type Gondoruwo struct { + Name string + Locatadata int +} + +type Sample struct { + ID int64 `faker:"customIdFaker"` + Gondoruwo Gondoruwo `faker:"gondoruwo"` + Danger string `faker:"danger"` +} + +func CustomGenerator() { + faker.AddProvider("customIdFaker", func(v reflect.Value) (interface{}, error) { + return int64(43), nil + }) + faker.AddProvider("danger", func(v reflect.Value) (interface{}, error) { + return "danger-ranger", nil + }) + + faker.AddProvider("gondoruwo", func(v reflect.Value) (interface{}, error) { + obj := Gondoruwo{ + Name: "Power", + Locatadata: 324, + } + return obj, nil + }) +} + +func main() { + CustomGenerator() + var sample Sample + faker.FakeData(&sample) + fmt.Printf("%+v", sample) +} +``` + +Results: +``` +{ID:43 Gondoruwo:{Name:Power Locatadata:324} Danger:danger-ranger} +``` + +## Without Tag +You also can use faker to generate your structs data randomly without any tag. And it will fill the data based on its data-type. ```go @@ -294,8 +339,11 @@ func main() { ``` +## DEMO + ![Example to use Faker](https://cdn-images-1.medium.com/max/800/1*AkMbxngg7zfvtWiuvFb4Mg.gif) +## Benchmark Bench To Generate Fake Data #### Without Tag ```bash diff --git a/address.go b/address.go index a7b561c..044fb08 100644 --- a/address.go +++ b/address.go @@ -25,35 +25,42 @@ func SetAddress(net Addresser) { // Addresser is logical layer for Address type Addresser interface { - Latitude(v reflect.Value) error - Longitude(v reflect.Value) error + Latitude(v reflect.Value) (interface{}, error) + Longitude(v reflect.Value) (interface{}, error) } // Address struct type Address struct{} +func (i Address) latitute() float32 { + return (rand.Float32() * 180) - 90 +} + // Latitude sets latitude of the address -func (i Address) Latitude(v reflect.Value) error { +func (i Address) Latitude(v reflect.Value) (interface{}, error) { kind := v.Kind() - val := (rand.Float32() * 180) - 90 + val := i.latitute() if kind == reflect.Float32 { v.Set(reflect.ValueOf(val)) - return nil + return float32(val), nil } v.Set(reflect.ValueOf(float64(val))) - return nil + return float64(val), nil +} + +func (i Address) longitude() float32 { + return (rand.Float32() * 360) - 180 } // Longitude sets longitude of the address -func (i Address) Longitude(v reflect.Value) error { +func (i Address) Longitude(v reflect.Value) (interface{}, error) { kind := v.Kind() - val := (rand.Float32() * 360) - 180 - + val := i.longitude() if kind == reflect.Float32 { v.Set(reflect.ValueOf(val)) - return nil + return float32(val), nil } v.Set(reflect.ValueOf(float64(val))) - return nil + return float64(val), nil } diff --git a/datetime.go b/datetime.go index c02f53e..0065be7 100644 --- a/datetime.go +++ b/datetime.go @@ -607,17 +607,17 @@ const ( // A DateTimer contains random Time generators, returning time string in certain particular format type DateTimer interface { - UnixTime(v reflect.Value) error - Date() string - Time() string - MonthName() string - Year() string - DayOfWeek() string - DayOfMonth() string - Timestamp() string - Century() string - TimeZone() string - TimePeriod() string + UnixTime(v reflect.Value) (interface{}, error) + Date(v reflect.Value) (interface{}, error) + Time(v reflect.Value) (interface{}, error) + MonthName(v reflect.Value) (interface{}, error) + Year(v reflect.Value) (interface{}, error) + DayOfWeek(v reflect.Value) (interface{}, error) + DayOfMonth(v reflect.Value) (interface{}, error) + Timestamp(v reflect.Value) (interface{}, error) + Century(v reflect.Value) (interface{}, error) + TimeZone(v reflect.Value) (interface{}, error) + TimePeriod(v reflect.Value) (interface{}, error) } var date DateTimer @@ -642,68 +642,111 @@ func SetDateTimer(d DateTimer) { type DateTime struct { } +func (d DateTime) unixtime() int64 { + return RandomUnixTime() +} + // UnixTime get unix time -func (d DateTime) UnixTime(v reflect.Value) error { +func (d DateTime) UnixTime(v reflect.Value) (interface{}, error) { kind := v.Kind() - + var val int64 if kind == reflect.Int64 { - v.SetInt(RandomUnixTime()) + val = d.unixtime() } else { - v.SetInt(0) + val = 0 } - return nil + v.SetInt(val) + return val, nil } -// Date formats DateTime using example BaseDate const -func (d DateTime) Date() string { +func (d DateTime) date() string { return time.Unix(RandomUnixTime(), 0).Format(BaseDate) } -// Time formats DateTime using example Time const -func (d DateTime) Time() string { +// Date formats DateTime using example BaseDate const +func (d DateTime) Date(v reflect.Value) (interface{}, error) { + return d.date(), nil +} + +func (d DateTime) time() string { return time.Unix(RandomUnixTime(), 0).Format(Time) } -// MonthName formats DateTime using example Month const -func (d DateTime) MonthName() string { +// Time formats DateTime using example Time const +func (d DateTime) Time(v reflect.Value) (interface{}, error) { + return d.time(), nil +} + +func (d DateTime) monthName() string { return time.Unix(RandomUnixTime(), 0).Format(Month) } -// Year formats DateTime using example Year const -func (d DateTime) Year() string { +// MonthName formats DateTime using example Month const +func (d DateTime) MonthName(v reflect.Value) (interface{}, error) { + return d.monthName(), nil +} + +func (d DateTime) year() string { return time.Unix(RandomUnixTime(), 0).Format(Year) } -// DayOfWeek formats DateTime using example Day const -func (d DateTime) DayOfWeek() string { +// Year formats DateTime using example Year const +func (d DateTime) Year(v reflect.Value) (interface{}, error) { + return d.year(), nil +} +func (d DateTime) dayOfWeek() string { return time.Unix(RandomUnixTime(), 0).Format(Day) } -// DayOfMonth formats DateTime using example DayOfMonth const -func (d DateTime) DayOfMonth() string { +// DayOfWeek formats DateTime using example Day const +func (d DateTime) DayOfWeek(v reflect.Value) (interface{}, error) { + return d.dayOfWeek(), nil +} + +func (d DateTime) dayOfMonth() string { return time.Unix(RandomUnixTime(), 0).Format(DayOfMonth) } -// Timestamp formats DateTime using example Timestamp const -func (d DateTime) Timestamp() string { +// DayOfMonth formats DateTime using example DayOfMonth const +func (d DateTime) DayOfMonth(v reflect.Value) (interface{}, error) { + return d.dayOfMonth(), nil +} + +func (d DateTime) timestamp() string { return time.Unix(RandomUnixTime(), 0).Format(fmt.Sprintf("%s %s", BaseDate, Time)) } -// Century returns a random century -func (d DateTime) Century() string { +// Timestamp formats DateTime using example Timestamp const +func (d DateTime) Timestamp(v reflect.Value) (interface{}, error) { + return d.timestamp(), nil +} +func (d DateTime) century() string { return randomElementFromSliceString(century) } -// TimeZone returns a random timezone -func (d DateTime) TimeZone() string { +// Century returns a random century +func (d DateTime) Century(v reflect.Value) (interface{}, error) { + return d.century(), nil +} + +func (d DateTime) timezone() string { return randomElementFromSliceString(timezones) } -// TimePeriod formats DateTime using example TimePeriod const -func (d DateTime) TimePeriod() string { +// TimeZone returns a random timezone +func (d DateTime) TimeZone(v reflect.Value) (interface{}, error) { + return d.timezone(), nil +} + +func (d DateTime) period() string { return time.Unix(RandomUnixTime(), 0).Format(TimePeriod) } +// TimePeriod formats DateTime using example TimePeriod const +func (d DateTime) TimePeriod(v reflect.Value) (interface{}, error) { + return d.period(), nil +} + // RandomUnixTime is a helper function returning random Unix time func RandomUnixTime() int64 { return rand.Int63n(time.Now().Unix()) diff --git a/datetime_test.go b/datetime_test.go index a7edc14..ce15d43 100644 --- a/datetime_test.go +++ b/datetime_test.go @@ -43,7 +43,11 @@ func TestUnixTimeValueNotValid(t *testing.T) { func TestDate(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(BaseDate, d.Date()) + date, err := d.Date(reflect.Value{}) + if err != nil { + t.Error("function Date need return valid value") + } + _, err = time.Parse(BaseDate, date.(string)) if err != nil { t.Error("function Date need return valid value") @@ -52,8 +56,11 @@ func TestDate(t *testing.T) { func TestTime(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(Time, d.Time()) - + tm, err := d.Time(reflect.Value{}) + if err != nil { + t.Error("function Time need return valid value") + } + _, err = time.Parse(Time, tm.(string)) if err != nil { t.Error("function Time need return valid value") } @@ -61,7 +68,11 @@ func TestTime(t *testing.T) { func TestMonthName(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(Month, d.MonthName()) + mt, err := d.MonthName(reflect.Value{}) + if err != nil { + t.Error("function Month need return valid month") + } + _, err = time.Parse(Month, mt.(string)) if err != nil { t.Error("function Month need return valid month") } @@ -69,7 +80,11 @@ func TestMonthName(t *testing.T) { func TestYear(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(Year, d.Year()) + year, err := d.Year(reflect.Value{}) + if err != nil { + t.Error("function Year need return valid year") + } + _, err = time.Parse(Year, year.(string)) if err != nil { t.Error("function Year need return valid year") } @@ -77,7 +92,11 @@ func TestYear(t *testing.T) { func TestDayOfWeek(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(Day, d.DayOfWeek()) + week, err := d.DayOfWeek(reflect.Value{}) + if err != nil { + t.Error("function DayOfWeek need return valid day") + } + _, err = time.Parse(Day, week.(string)) if err != nil { t.Error("function DayOfWeek need return valid day") } @@ -87,12 +106,15 @@ func TestDayOfWeekReturnsDifferentValues(t *testing.T) { dayMap := make(map[string]struct{}) iterations := 5 // sufficiently large to assure we don't randomly get the same value again for i := 0; i < iterations; i++ { - day := GetDateTimer().DayOfWeek() - if _, ok := dayMap[day]; ok { + day, err := GetDateTimer().DayOfWeek(reflect.Value{}) + if err != nil { + t.Error("function DayOfWeek need return valid day") + } + if _, ok := dayMap[day.(string)]; ok { i-- continue } - dayMap[day] = struct{}{} + dayMap[day.(string)] = struct{}{} t.Log(day) // Will print random and different day 5 times. } @@ -104,7 +126,11 @@ func TestDayOfWeekReturnsDifferentValues(t *testing.T) { func TestDayOfMonth(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(DayOfMonth, d.DayOfMonth()) + mt, err := d.DayOfMonth(reflect.Value{}) + if err != nil { + t.Error("function DayOfMonth need return valid digit") + } + _, err = time.Parse(DayOfMonth, mt.(string)) if err != nil { t.Error("function DayOfMonth need return valid digit") } @@ -112,7 +138,11 @@ func TestDayOfMonth(t *testing.T) { func TestTimestamp(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(fmt.Sprintf("%s %s", BaseDate, Time), d.Timestamp()) + tstmp, err := d.Timestamp(reflect.Value{}) + if err != nil { + t.Error("function Timestamp need return valid timestamp format") + } + _, err = time.Parse(fmt.Sprintf("%s %s", BaseDate, Time), tstmp.(string)) if err != nil { t.Error("function Timestamp need return valid timestamp format") } @@ -120,22 +150,33 @@ func TestTimestamp(t *testing.T) { func TestCentury(t *testing.T) { d := GetDateTimer() - - if !slice.Contains(century, d.Century()) { + centry, err := d.Century(reflect.Value{}) + if err != nil { + t.Error("Expected century from functuon Century") + } + if !slice.Contains(century, centry.(string)) { t.Error("Expected century from functuon Century") } } func TestTimeZone(t *testing.T) { d := GetDateTimer() - if !slice.Contains(timezones, d.TimeZone()) { + tz, err := d.TimeZone(reflect.Value{}) + if err != nil { + t.Error("Expected timezone from variable timezones") + } + if !slice.Contains(timezones, tz.(string)) { t.Error("Expected timezone from variable timezones") } } func TestTimePeriod(t *testing.T) { d := GetDateTimer() - _, err := time.Parse(TimePeriod, d.TimePeriod()) + periode, err := d.TimePeriod(reflect.Value{}) + if err != nil { + t.Error("function TimePeriod need return valid period") + } + _, err = time.Parse(TimePeriod, periode.(string)) if err != nil { t.Error("function TimePeriod need return valid period") } diff --git a/faker.go b/faker.go index 6438b5e..7321fe6 100644 --- a/faker.go +++ b/faker.go @@ -64,7 +64,10 @@ const ( SKIP = "-" ) -var mapperTag = map[string]interface{}{ +// TaggedFunction ... +type TaggedFunction func(v reflect.Value) (interface{}, error) + +var mapperTag = map[string]TaggedFunction{ Email: GetNetworker().Email, MacAddress: GetNetworker().MacAddress, DomainName: GetNetworker().DomainName, @@ -156,7 +159,7 @@ func FakeData(a interface{}) error { } // AddProvider extend faker with tag to generate fake data with specified custom algoritm -func AddProvider(tag string, provider interface{}) error { +func AddProvider(tag string, provider TaggedFunction) error { if _, ok := mapperTag[tag]; ok { return errors.New(ErrTagAlreadyExists) } @@ -297,6 +300,16 @@ func setDataWithTag(v reflect.Value, tag string) error { case reflect.Int, reflect.Int32, reflect.Int64, reflect.Int8, reflect.Int16: return userDefinedInt(v, tag) + default: + if _, exist := mapperTag[tag]; !exist { + return errors.New(ErrTagNotSupported) + } + res, err := mapperTag[tag](v) + if err != nil { + return err + } + v.Set(reflect.ValueOf(res)) + } return nil } @@ -305,7 +318,11 @@ func userDefinedFloat(v reflect.Value, tag string) error { if _, exist := mapperTag[tag]; !exist { return errors.New(ErrTagNotSupported) } - mapperTag[tag].(func(v reflect.Value) error)(v) + res, err := mapperTag[tag](v) + if err != nil { + return err + } + v.Set(reflect.ValueOf(res)) return nil } @@ -314,7 +331,11 @@ func userDefinedString(v reflect.Value, tag string) error { if _, exist := mapperTag[tag]; !exist { return errors.New(ErrTagNotSupported) } - val = mapperTag[tag].(func() string)() + item, err := mapperTag[tag](v) + if err != nil { + return err + } + val, _ = item.(string) v.SetString(val) return nil } @@ -323,7 +344,12 @@ func userDefinedInt(v reflect.Value, tag string) error { if _, exist := mapperTag[tag]; !exist { return errors.New(ErrTagNotSupported) } - mapperTag[tag].(func(v reflect.Value) error)(v) + val, err := mapperTag[tag](v) + if err != nil { + return err + } + + v.Set(reflect.ValueOf(val)) return nil } diff --git a/faker_test.go b/faker_test.go index 34de8cd..bf103b4 100644 --- a/faker_test.go +++ b/faker_test.go @@ -27,7 +27,7 @@ type SomeStruct struct { LATITUDE float64 `faker:"lat"` Long float32 `faker:"long"` LONG float64 `faker:"long"` - String string + StringValue string CreditCardType string `faker:"cc_type"` CreditCardNumber string `faker:"cc_number"` Email string `faker:"email"` @@ -56,6 +56,67 @@ type SomeStruct struct { MapStringStruct map[string]AStruct MapStringStructPointer map[string]*AStruct } + +func (s SomeStruct) String() string { + return fmt.Sprintf(`{ + Inta: %v + Int8: %v + Int16: %v + Int32: %v + Int64: %v + Float32: %v + Float64: %v + + UInta: %v + UInt8: %v + UInt16: %v + UInt32: %v + UInt64: %v + + Latitude: %v + LATITUDE: %v + Long: %v + LONG: %v + StringValue: %v + CreditCardType: %v + CreditCardNumber: %v + Email: %v + IPV4: %v + IPV6: %v + Bool: %v + SString: %v + SInt: %v + SInt8: %v + SInt16: %v + SInt32: %v + SInt64: %v + SFloat32: %v + SFloat64:%v + SBool: %v + Struct: %v + Time: %v + Stime: %v + Currency: %v + Amount: %v + AmountWithCurrency: %v + ID: %v + HyphenatedID: %v + + MapStringString: %v + MapStringStruct: %v + MapStringStructPointer: %v + }`, s.Inta, s.Int8, s.Int16, s.Int32, + s.Int64, s.Float32, s.Float64, s.UInta, + s.UInt8, s.UInt16, s.UInt32, s.UInt64, + s.Latitude, s.LATITUDE, s.Long, s.LONG, + s.StringValue, s.CreditCardType, s.CreditCardNumber, + s.Email, s.IPV4, s.IPV6, s.Bool, s.SString, s.SInt, + s.SInt8, s.SInt16, s.SInt32, s.SInt64, s.SFloat32, s.SFloat64, + s.SBool, s.Struct, s.Time, s.Stime, s.Currency, s.Amount, + s.AmountWithCurrency, s.ID, s.HyphenatedID, s.MapStringString, + s.MapStringStruct, s.MapStringStructPointer) +} + type AStruct struct { Number int64 Height int64 @@ -252,33 +313,11 @@ func TestSetDataErrorDataParseTagIntType(t *testing.T) { func TestSetDataWithTagIfFirstArgumentNotPtr(t *testing.T) { temp := struct{}{} - if "Not a pointer value" != setDataWithTag(reflect.ValueOf(temp), "").Error() { + if setDataWithTag(reflect.ValueOf(temp), "").Error() != "Not a pointer value" { t.Error("Expected in arguments not ptr") } } -func TestSetDataWithTagIfFirstArgumentSlice(t *testing.T) { - temp := []int{} - if setDataWithTag(reflect.ValueOf(&temp), "") != nil { - t.Error("Not expected errors if first argument slice type") - } -} - -func TestSetDataWithTagIfFirstArgumentNotFound(t *testing.T) { - temp := struct{}{} - if setDataWithTag(reflect.ValueOf(&temp), "") != nil { - t.Error("First argument is struct type, expected return nil") - } -} - -func TestUserDefinedFloatNotFoundTag(t *testing.T) { - temp := struct{}{} - - if userDefinedFloat(reflect.ValueOf(&temp), "") == nil { - t.Error("Not expected errors") - } -} - func BenchmarkFakerDataNOTTagged(b *testing.B) { for i := 0; i < b.N; i++ { a := NotTaggedStruct{} @@ -434,36 +473,75 @@ func TestSkipField(t *testing.T) { } +type Student struct { + Name string + School School `faker:"custom-school"` +} +type School struct { + Location string +} + func TestExtend(t *testing.T) { // This test is to ensure that faker can be extended new providers - a := struct { - ID string `faker:"test"` - }{} + t.Run("test-string", func(t *testing.T) { + a := struct { + ID string `faker:"test"` + }{} + + err := AddProvider("test", func(v reflect.Value) (interface{}, error) { + return "test", nil + }) + + if err != nil { + t.Error("Expected Not Error, But Got: ", err) + } + + err = FakeData(&a) + + if err != nil { + t.Error("Expected Not Error, But Got: ", err) + } - err := AddProvider("test", func() string { - return "test" + if a.ID != "test" { + t.Error("ID should be equal test value") + } }) - if err != nil { - t.Error("Expected Not Error, But Got: ", err) - } + t.Run("test-struct", func(t *testing.T) { + a := &Student{} + err := AddProvider("custom-school", func(v reflect.Value) (interface{}, error) { - err = FakeData(&a) + sch := School{ + Location: "North Kindom", + } - if err != nil { - t.Error("Expected Not Error, But Got: ", err) - } + return sch, nil + }) + + if err != nil { + t.Error("Expected Not Error, But Got: ", err) + } + + err = FakeData(&a) + + if err != nil { + t.Error("Expected Not Error, But Got: ", err) + } + + if a.School.Location != "North Kindom" { + t.Error("ID should be equal test value") + } + }) - if a.ID != "test" { - t.Error("ID should be equal test value") - } } func TestTagAlreadyExists(t *testing.T) { // This test is to ensure that existing tag cannot be rewritten - err := AddProvider(Email, func() {}) + err := AddProvider(Email, func(v reflect.Value) (interface{}, error) { + return nil, nil + }) if err == nil || err.Error() != ErrTagAlreadyExists { t.Error("Expected ErrTagAlreadyExists Error, But Got: ", err) diff --git a/internet.go b/internet.go index df521cc..1cb17ec 100644 --- a/internet.go +++ b/internet.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "net" + "reflect" "strings" ) @@ -42,26 +43,29 @@ func SetNetwork(net Networker) { // Networker is logical layer for Internet type Networker interface { - Email() string - MacAddress() string - DomainName() string - URL() string - UserName() string - IPv4() string - IPv6() string - Password() string + Email(v reflect.Value) (interface{}, error) + MacAddress(v reflect.Value) (interface{}, error) + DomainName(v reflect.Value) (interface{}, error) + URL(v reflect.Value) (interface{}, error) + UserName(v reflect.Value) (interface{}, error) + IPv4(v reflect.Value) (interface{}, error) + IPv6(v reflect.Value) (interface{}, error) + Password(v reflect.Value) (interface{}, error) } // Internet struct type Internet struct{} -// Email generates random email id -func (internet Internet) Email() string { +func (internet Internet) email() string { return randomString(7) + "@" + randomString(5) + "." + randomElementFromSliceString(tld) } -// MacAddress generates random MacAddress -func (internet Internet) MacAddress() string { +// Email generates random email id +func (internet Internet) Email(v reflect.Value) (interface{}, error) { + return internet.email(), nil +} + +func (internet Internet) macAddress() string { ip := make([]byte, 6) for i := 0; i < 6; i++ { ip[i] = byte(rand.Intn(256)) @@ -69,28 +73,44 @@ func (internet Internet) MacAddress() string { return net.HardwareAddr(ip).String() } -// DomainName generates random domain name -func (internet Internet) DomainName() string { +// MacAddress generates random MacAddress +func (internet Internet) MacAddress(v reflect.Value) (interface{}, error) { + return internet.macAddress(), nil +} + +func (internet Internet) domainName() string { return randomString(7) + "." + randomElementFromSliceString(tld) } -// URL generates random URL standardised in urlFormats const -func (internet Internet) URL() string { +// DomainName generates random domain name +func (internet Internet) DomainName(v reflect.Value) (interface{}, error) { + return internet.domainName(), nil +} + +func (internet Internet) url() string { format := randomElementFromSliceString(urlFormats) countVerbs := strings.Count(format, "%s") if countVerbs == 1 { - return fmt.Sprintf(format, internet.DomainName()) + return fmt.Sprintf(format, internet.domainName()) } - return fmt.Sprintf(format, internet.DomainName(), internet.UserName()) + return fmt.Sprintf(format, internet.domainName(), internet.username()) } -// UserName generates random username -func (internet Internet) UserName() string { +// URL generates random URL standardised in urlFormats const +func (internet Internet) URL(v reflect.Value) (interface{}, error) { + return internet.url(), nil +} + +func (internet Internet) username() string { return randomString(7) } -// IPv4 generates random IPv4 address -func (internet Internet) IPv4() string { +// UserName generates random username +func (internet Internet) UserName(v reflect.Value) (interface{}, error) { + return internet.username(), nil +} + +func (internet Internet) ipv4() string { size := 4 ip := make([]byte, size) for i := 0; i < size; i++ { @@ -99,8 +119,12 @@ func (internet Internet) IPv4() string { return net.IP(ip).To4().String() } -// IPv6 generates random IPv6 address -func (internet Internet) IPv6() string { +// IPv4 generates random IPv4 address +func (internet Internet) IPv4(v reflect.Value) (interface{}, error) { + return internet.ipv4(), nil +} + +func (internet Internet) ipv6() string { size := 16 ip := make([]byte, size) for i := 0; i < size; i++ { @@ -109,7 +133,16 @@ func (internet Internet) IPv6() string { return net.IP(ip).To16().String() } -// Password returns a hashed password -func (internet Internet) Password() string { +// IPv6 generates random IPv6 address +func (internet Internet) IPv6(v reflect.Value) (interface{}, error) { + return internet.ipv6(), nil +} + +func (internet Internet) password() string { return randomString(50) } + +// Password returns a hashed password +func (internet Internet) Password(v reflect.Value) (interface{}, error) { + return internet.password(), nil +} diff --git a/internet_test.go b/internet_test.go index ca12193..9b8732c 100644 --- a/internet_test.go +++ b/internet_test.go @@ -1,6 +1,7 @@ package faker import ( + "reflect" "strings" "testing" @@ -8,19 +9,32 @@ import ( ) func TestEmail(t *testing.T) { - if !strings.Contains(GetNetworker().Email(), "@") { + email, err := GetNetworker().Email(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !strings.Contains(email.(string), "@") { t.Error("Expected email") } } func TestMacAddress(t *testing.T) { i := Internet{} + mc, err := i.MacAddress(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } - if strings.Count(i.MacAddress(), ":") != 5 { + if strings.Count(mc.(string), ":") != 5 { t.Error("Expected mac address") } } func TestDomainName(t *testing.T) { - preTld := strings.Split(GetNetworker().DomainName(), ".") + domain, err := GetNetworker().DomainName(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + + preTld := strings.Split(domain.(string), ".") if !slice.Contains(tld, preTld[1]) { t.Error("Expected get DomainName") @@ -29,41 +43,64 @@ func TestDomainName(t *testing.T) { func TestURLOneVerbs(t *testing.T) { urlFormats = []string{ "http://www.%s/"} - - if !strings.Contains(GetNetworker().URL(), "http") { + res, err := GetNetworker().URL(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !strings.Contains(res.(string), "http") { t.Error("Expected get url") } } func TestURLTwoVerbs(t *testing.T) { urlFormats = []string{ "http://www.%s/%s"} - - if !strings.Contains(GetNetworker().URL(), "http") { + res, err := GetNetworker().URL(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !strings.Contains(res.(string), "http") { t.Error("Expected get url") } } func TestUserName(t *testing.T) { - if GetNetworker().UserName() == "" { + usrname, err := GetNetworker().UserName(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if usrname.(string) == "" { t.Error("Expected get username") } } func TestIPv4(t *testing.T) { - if strings.Count(GetNetworker().IPv4(), ".") != 3 { + ip, err := GetNetworker().IPv4(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if strings.Count(ip.(string), ".") != 3 { t.Error("Expected IPv4 format") } } func TestIPv6(t *testing.T) { - if strings.Count(GetNetworker().IPv6(), ":") != 7 { + ip, err := GetNetworker().IPv6(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if strings.Count(ip.(string), ":") != 7 { t.Error("Expected IPv4 format") } } func TestSetNetwork(t *testing.T) { + SetNetwork(Internet{}) } func TestPassword(t *testing.T) { - if GetNetworker().Password() == "" { + pass, err := GetNetworker().Password(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if pass.(string) == "" { t.Error("Expected hash password") } } diff --git a/lorem.go b/lorem.go index 27ef5e5..8556160 100644 --- a/lorem.go +++ b/lorem.go @@ -3,6 +3,7 @@ package faker import ( "fmt" "math/rand" + "reflect" "strings" ) @@ -49,9 +50,9 @@ var wordList = []string{ // DataFaker generates randomized Words, Sentences and Paragraphs type DataFaker interface { - Word() string - Sentence() string - Paragraph() string + Word(v reflect.Value) (interface{}, error) + Sentence(v reflect.Value) (interface{}, error) + Paragraph(v reflect.Value) (interface{}, error) } // SetDataFaker sets Custom data in lorem @@ -74,13 +75,17 @@ func GetLorem() DataFaker { type Lorem struct { } -// Word returns a word from the wordList const -func (l Lorem) Word() string { +func (l Lorem) word() string { return randomElementFromSliceString(wordList) } -// Sentence returns a sentence using the wordList const -func (l Lorem) Sentence() (sentence string) { +// Word returns a word from the wordList const +func (l Lorem) Word(v reflect.Value) (interface{}, error) { + return l.word(), nil +} + +func (l Lorem) sentence() string { + sentence := "" r, _ := RandomInt(1, 6) size := len(r) for key, val := range r { @@ -96,14 +101,25 @@ func (l Lorem) Sentence() (sentence string) { return fmt.Sprintf("%s.", sentence) } -// Paragraph returns a series of sentences as a paragraph using the wordList const -func (l Lorem) Paragraph() (paragraph string) { +// Sentence returns a sentence using the wordList const +func (l Lorem) Sentence(v reflect.Value) (interface{}, error) { + sentence := l.sentence() + return sentence, nil +} + +func (l Lorem) paragraph() string { + paragraph := "" size := rand.Intn(10) + 1 for i := 0; i < size; i++ { - paragraph += l.Sentence() + paragraph += l.sentence() if i != size-1 { paragraph += " " } } return paragraph } + +// Paragraph returns a series of sentences as a paragraph using the wordList const +func (l Lorem) Paragraph(v reflect.Value) (interface{}, error) { + return l.paragraph(), nil +} diff --git a/lorem_test.go b/lorem_test.go index 91c5555..c954700 100644 --- a/lorem_test.go +++ b/lorem_test.go @@ -1,6 +1,8 @@ package faker import ( + "fmt" + "reflect" "strings" "testing" @@ -12,20 +14,33 @@ func TestDataFaker(t *testing.T) { } func TestWord(t *testing.T) { - if !slice.Contains(wordList, GetLorem().Word()) { + word, err := GetLorem().Word(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(wordList, word.(string)) { t.Error("Expected word from slice wordList") } } func TestSentence(t *testing.T) { - s := GetLorem().Sentence() + res, err := GetLorem().Sentence(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + s := res.(string) if s == "" || !strings.HasSuffix(s, ".") { t.Error("Expected sentence") } } func TestParagraph(t *testing.T) { - s := GetLorem().Paragraph() + res, err := GetLorem().Paragraph(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + s := res.(string) + fmt.Println(s) if s == "" || !strings.HasSuffix(s, ".") { t.Error("Expected paragraph") } diff --git a/payment.go b/payment.go index 31b73e4..6659128 100644 --- a/payment.go +++ b/payment.go @@ -2,8 +2,8 @@ package faker import ( "math/rand" + "reflect" "strconv" - "strings" ) const ( @@ -22,6 +22,10 @@ var creditCards = map[string]creditCard{ "mastercard": {"MasterCard", 16, []int{51, 52, 53, 54, 55}}, "american express": {"American Express", 15, []int{34, 37}}, "discover": {"Discover", 16, []int{6011}}, + "VISA": {"VISA", 16, []int{4539, 4556, 4916, 4532, 4929, 40240071, 4485, 4716, 4}}, + "MasterCard": {"MasterCard", 16, []int{51, 52, 53, 54, 55}}, + "American Express": {"American Express", 15, []int{34, 37}}, + "Discover": {"Discover", 16, []int{6011}}, } var pay Render @@ -46,16 +50,14 @@ func SetPayment(p Render) { // Render contains Whole Random Credit Card Generators with their types type Render interface { - CreditCardType() string - CreditCardNumber() string + CreditCardType(v reflect.Value) (interface{}, error) + CreditCardNumber(v reflect.Value) (interface{}, error) } // Payment struct type Payment struct{} -// CreditCardType returns one of the following credit values: -// VISA, MasterCard, American Express and Discover -func (p Payment) CreditCardType() string { +func (p Payment) cctype() string { n := len(creditCards) if cacheCreditCard != "" { return cacheCreditCard @@ -69,9 +71,14 @@ func (p Payment) CreditCardType() string { return cacheCreditCard } -// CreditCardNumber generated credit card number according to the card number rules -func (p Payment) CreditCardNumber() string { - ccType := strings.ToLower(p.CreditCardType()) +// CreditCardType returns one of the following credit values: +// VISA, MasterCard, American Express and Discover +func (p Payment) CreditCardType(v reflect.Value) (interface{}, error) { + return p.cctype(), nil +} + +func (p Payment) ccnumber() string { + ccType := p.cctype() cacheCreditCard = ccType card := creditCards[ccType] prefix := strconv.Itoa(card.prefixes[rand.Intn(len(card.prefixes))]) @@ -82,3 +89,8 @@ func (p Payment) CreditCardNumber() string { num += digit return num } + +// CreditCardNumber generated credit card number according to the card number rules +func (p Payment) CreditCardNumber(v reflect.Value) (interface{}, error) { + return p.ccnumber(), nil +} diff --git a/payment_test.go b/payment_test.go index 25c75c0..c28ebeb 100644 --- a/payment_test.go +++ b/payment_test.go @@ -1,19 +1,25 @@ package faker import ( + "reflect" "strings" "testing" ) func TestCreditCardType(t *testing.T) { - randCC := strings.ToLower(GetPayment().CreditCardType()) + ccType, err := GetPayment().CreditCardType(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + randCC := strings.ToLower(ccType.(string)) + if _, exist := creditCards[randCC]; !exist { t.Errorf("Expected from function creditCardType() : %s", randCC) } } func TestCreditCardNumber(t *testing.T) { - GetPayment().CreditCardNumber() + GetPayment().CreditCardNumber(reflect.Value{}) } func TestSetPayment(t *testing.T) { diff --git a/person.go b/person.go index e7fe80a..5365379 100644 --- a/person.go +++ b/person.go @@ -3,17 +3,18 @@ package faker import ( "fmt" "math/rand" + "reflect" ) // Dowser provides interfaces to generate random logical Names with their initials type Dowser interface { - TitleMale() string - TitleFeMale() string - FirstName() string - FirstNameMale() string - FirstNameFemale() string - LastName() string - Name() string + TitleMale(v reflect.Value) (interface{}, error) + TitleFeMale(v reflect.Value) (interface{}, error) + FirstName(v reflect.Value) (interface{}, error) + FirstNameMale(v reflect.Value) (interface{}, error) + FirstNameFemale(v reflect.Value) (interface{}, error) + LastName(v reflect.Value) (interface{}, error) + Name(v reflect.Value) (interface{}, error) } var person Dowser @@ -127,40 +128,68 @@ func SetDowser(d Dowser) { type Person struct { } -// TitleMale generates random titles for males -func (p Person) TitleMale() string { +func (p Person) titlemale() string { return randomElementFromSliceString(titlesMale) } -// TitleFeMale generates random titles for females -func (p Person) TitleFeMale() string { +// TitleMale generates random titles for males +func (p Person) TitleMale(v reflect.Value) (interface{}, error) { + return p.titlemale(), nil +} + +func (p Person) titleFemale() string { return randomElementFromSliceString(titlesFemale) } -// FirstName retuns first names -func (p Person) FirstName() string { +// TitleFeMale generates random titles for females +func (p Person) TitleFeMale(v reflect.Value) (interface{}, error) { + return p.titleFemale(), nil +} + +func (p Person) firstname() string { return randomElementFromSliceString(firstNames) } -// FirstNameMale retuns first names for males -func (p Person) FirstNameMale() string { +// FirstName retuns first names +func (p Person) FirstName(v reflect.Value) (interface{}, error) { + return p.firstname(), nil +} + +func (p Person) firstnamemale() string { return randomElementFromSliceString(firstNamesMale) } -// FirstNameFemale retuns first names for females -func (p Person) FirstNameFemale() string { +// FirstNameMale retuns first names for males +func (p Person) FirstNameMale(v reflect.Value) (interface{}, error) { + return p.firstnamemale(), nil +} + +func (p Person) firstnamefemale() string { return randomElementFromSliceString(firstNamesFemale) } -// LastName returns last name -func (p Person) LastName() string { +// FirstNameFemale retuns first names for females +func (p Person) FirstNameFemale(v reflect.Value) (interface{}, error) { + return p.firstnamefemale(), nil +} + +func (p Person) lastname() string { return randomElementFromSliceString(lastNames) } -// Name returns a random name -func (p Person) Name() string { +// LastName returns last name +func (p Person) LastName(v reflect.Value) (interface{}, error) { + return p.lastname(), nil +} + +func (p Person) name() string { if randNameFlag > 50 { return fmt.Sprintf("%s %s %s", randomElementFromSliceString(titlesFemale), randomElementFromSliceString(firstNamesFemale), randomElementFromSliceString(lastNames)) } return fmt.Sprintf("%s %s %s", randomElementFromSliceString(titlesMale), randomElementFromSliceString(firstNamesMale), randomElementFromSliceString(lastNames)) } + +// Name returns a random name +func (p Person) Name(v reflect.Value) (interface{}, error) { + return p.name(), nil +} diff --git a/person_test.go b/person_test.go index 8435cc5..894f732 100644 --- a/person_test.go +++ b/person_test.go @@ -1,6 +1,7 @@ package faker import ( + "reflect" "testing" "github.com/bxcodec/faker/support/slice" @@ -11,58 +12,82 @@ func TestSetDowser(t *testing.T) { } func TestTitleMale(t *testing.T) { - p := GetPerson() - if !slice.Contains(titlesMale, p.TitleMale()) { + male, err := GetPerson().TitleMale(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(titlesMale, male.(string)) { t.Error("Expected value from variable titleMales in function TitleMale") } } func TestTitleFemale(t *testing.T) { - p := GetPerson() - if !slice.Contains(titlesFemale, p.TitleFeMale()) { + female, err := GetPerson().TitleFeMale(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(titlesFemale, female.(string)) { t.Error("Expected value from variable titleFemales in function TitleFeMale") } } func TestFirstNameMale(t *testing.T) { - p := GetPerson() - if !slice.Contains(firstNamesMale, p.FirstNameMale()) { + firstName, err := GetPerson().FirstNameMale(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(firstNamesMale, firstName.(string)) { t.Error("Expected value from variable firstNamesMale in function FirstNameMale") } } func TestFirstNameFemale(t *testing.T) { - p := GetPerson() - if !slice.Contains(firstNamesFemale, p.FirstNameFemale()) { + firstName, err := GetPerson().FirstNameFemale(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(firstNamesFemale, firstName.(string)) { t.Error("Expected value from variable firstNamesFemale in function FirstNameFemale") } } func TestFirstName(t *testing.T) { - p := GetPerson() - if !slice.Contains(firstNames, p.FirstName()) { + firstname, err := GetPerson().FirstName(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(firstNames, firstname.(string)) { t.Error("Expected value from either firstNamesMale or firstNamesFemale in function FirstName") } } func TestLastName(t *testing.T) { - p := GetPerson() - if !slice.Contains(lastNames, p.LastName()) { + lastname, err := GetPerson().LastName(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(lastNames, lastname.(string)) { t.Error("Expected value from variable lastNames in function LastName") } } func TestNameMale(t *testing.T) { - p := GetPerson() + name, err := GetPerson().Name(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } randNameFlag = 51 - if p.Name() == "" { + if name.(string) == "" { t.Error("Expected from function name string get empty string") } } func TestNameFemale(t *testing.T) { - p := GetPerson() + name, err := GetPerson().Name(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } randNameFlag = 20 - if p.Name() == "" { + if name.(string) == "" { t.Error("Expected from function name string get empty string") } } diff --git a/phone.go b/phone.go index 1e68ad6..1a27c7e 100644 --- a/phone.go +++ b/phone.go @@ -3,6 +3,7 @@ package faker import ( "fmt" "math/rand" + "reflect" "strings" "github.com/bxcodec/faker/support/slice" @@ -28,24 +29,27 @@ func SetPhoner(p Phoner) { // Phoner serves overall tele-phonic contact generator type Phoner interface { - PhoneNumber() string - TollFreePhoneNumber() string - E164PhoneNumber() string + PhoneNumber(v reflect.Value) (interface{}, error) + TollFreePhoneNumber(v reflect.Value) (interface{}, error) + E164PhoneNumber(v reflect.Value) (interface{}, error) } // Phone struct type Phone struct { } -// PhoneNumber generates phone numbers of type: "201-886-0269" -func (p Phone) PhoneNumber() string { +func (p Phone) phonenumber() string { randInt, _ := RandomInt(1, 10) str := strings.Join(slice.IntToString(randInt), "") return fmt.Sprintf("%s-%s-%s", str[:3], str[3:6], str[6:10]) } -// TollFreePhoneNumber generates phone numbers of type: "(888) 937-7238" -func (p Phone) TollFreePhoneNumber() string { +// PhoneNumber generates phone numbers of type: "201-886-0269" +func (p Phone) PhoneNumber(v reflect.Value) (interface{}, error) { + return p.phonenumber(), nil +} + +func (p Phone) tollfreephonenumber() string { out := "" boxDigitsStart := []string{"777", "888"} @@ -59,8 +63,12 @@ func (p Phone) TollFreePhoneNumber() string { return fmt.Sprintf("(%s) %s", boxDigitsStart[rand.Intn(1)], out) } -// E164PhoneNumber generates phone numbers of type: "+27113456789" -func (p Phone) E164PhoneNumber() string { +// TollFreePhoneNumber generates phone numbers of type: "(888) 937-7238" +func (p Phone) TollFreePhoneNumber(v reflect.Value) (interface{}, error) { + return p.tollfreephonenumber(), nil +} + +func (p Phone) e164PhoneNumber() string { out := "" boxDigitsStart := []string{"7", "8"} ints, _ := RandomInt(1, 10) @@ -70,3 +78,8 @@ func (p Phone) E164PhoneNumber() string { } return fmt.Sprintf("+%s%s", boxDigitsStart[rand.Intn(1)], strings.Join(slice.IntToString(ints), "")) } + +// E164PhoneNumber generates phone numbers of type: "+27113456789" +func (p Phone) E164PhoneNumber(v reflect.Value) (interface{}, error) { + return p.e164PhoneNumber(), nil +} diff --git a/phone_test.go b/phone_test.go index 8bc9a0a..40295f6 100644 --- a/phone_test.go +++ b/phone_test.go @@ -1,28 +1,37 @@ package faker import ( + "reflect" "strings" "testing" ) func TestPhoneNumber(t *testing.T) { - ph := GetPhoner() - if strings.Count(ph.PhoneNumber(), "-") != 2 { + ph, err := GetPhoner().PhoneNumber(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if strings.Count(ph.(string), "-") != 2 { t.Error("Expected no more than two characters '-'") } } func TestTollFreePhoneNumber(t *testing.T) { - ph := GetPhoner() - - if !strings.HasPrefix(ph.TollFreePhoneNumber(), "(888)") && !strings.HasPrefix(ph.TollFreePhoneNumber(), "(777)") { + ph, err := GetPhoner().TollFreePhoneNumber(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !strings.HasPrefix(ph.(string), "(888)") && !strings.HasPrefix(ph.(string), "(777)") { t.Error("Expected character '(888)' or (777), in function TollFreePhoneNumber") } } func TestE164PhoneNumber(t *testing.T) { - ph := GetPhoner() - if !strings.HasPrefix(ph.E164PhoneNumber(), "+") { + ph, err := GetPhoner().E164PhoneNumber(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !strings.HasPrefix(ph.(string), "+") { t.Error("Expected character '(888)', in function TollFreePhoneNumber") } } diff --git a/price.go b/price.go index 5ae3363..db51f2d 100644 --- a/price.go +++ b/price.go @@ -33,9 +33,9 @@ var currencies = []string{ // Money provides an interface to generate a custom price with or without a random currency code type Money interface { - Currency() string - Amount(v reflect.Value) error - AmountWithCurrency() string + Currency(v reflect.Value) (interface{}, error) + Amount(v reflect.Value) (interface{}, error) + AmountWithCurrency(v reflect.Value) (interface{}, error) } // Price struct @@ -60,28 +60,40 @@ func SetPrice(p Money) { pri = p } -// Currency returns a random currency from currencies -func (p Price) Currency() string { +func (p Price) currency() string { return randomElementFromSliceString(currencies) } +// Currency returns a random currency from currencies +func (p Price) Currency(v reflect.Value) (interface{}, error) { + return p.currency(), nil +} + +func (p Price) amount() float64 { + return precision(rand.Float64()*math.Pow10(rand.Intn(8)), rand.Intn(2)+1) +} + // Amount returns a random floating price amount // with a random precision of [1,2] up to (10**8 - 1) -func (p Price) Amount(v reflect.Value) error { +func (p Price) Amount(v reflect.Value) (interface{}, error) { kind := v.Kind() - val := precision(rand.Float64()*math.Pow10(rand.Intn(8)), rand.Intn(2)+1) + val := p.amount() if kind == reflect.Float32 { v.Set(reflect.ValueOf(float32(val))) - return nil + return float32(val), nil } v.Set(reflect.ValueOf(val)) - return nil + return val, nil +} + +func (p Price) amountwithcurrency() string { + val := p.amount() + return fmt.Sprintf("%s %f", p.currency(), val) } // AmountWithCurrency combines both price and currency together -func (p Price) AmountWithCurrency() string { - val := precision(rand.Float64()*math.Pow10(rand.Intn(8)), rand.Intn(2)+1) - return fmt.Sprintf("%s %f", p.Currency(), val) +func (p Price) AmountWithCurrency(v reflect.Value) (interface{}, error) { + return p.amountwithcurrency(), nil } // precision | a helper function to set precision of price diff --git a/price_test.go b/price_test.go index 6ea5391..9b327f3 100644 --- a/price_test.go +++ b/price_test.go @@ -1,7 +1,7 @@ package faker import ( - "fmt" + "reflect" "strings" "testing" @@ -13,17 +13,22 @@ func TestSetPrice(t *testing.T) { } func TestCurrency(t *testing.T) { - p := GetPrice() - fmt.Println(p.Currency()) - if !slice.Contains(currencies, p.Currency()) { + p, err := GetPrice().Currency(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if !slice.Contains(currencies, p.(string)) { t.Error("Expected a currency code from currencies") } } func TestAmountWithCurrency(t *testing.T) { - p := GetPrice() - fmt.Println(p.AmountWithCurrency()) - if !strings.Contains(p.AmountWithCurrency(), " ") { + p, err := GetPrice().AmountWithCurrency(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + + if !strings.Contains(p.(string), " ") { t.Error("Expected Price currency followed by a space and it's ammount") } } diff --git a/uuid.go b/uuid.go index e260da8..04081f3 100644 --- a/uuid.go +++ b/uuid.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "fmt" "io" + "reflect" ) var identifier Identifier @@ -21,8 +22,8 @@ func GetIdentifier() Identifier { // Identifier ... type Identifier interface { - Digit() string - Hyphenated() string + Digit(v reflect.Value) (interface{}, error) + Hyphenated(v reflect.Value) (interface{}, error) } // UUID struct @@ -39,16 +40,25 @@ func createUUID() []byte { return b } -// Hyphenated returns a 36 byte hyphenated UUID -func (i UUID) Hyphenated() string { +func (u UUID) hyphenated() string { b := createUUID() uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) return uuid } -// Digit returns a 32 bytes UUID -func (i UUID) Digit() string { +// Hyphenated returns a 36 byte hyphenated UUID +func (i UUID) Hyphenated(v reflect.Value) (interface{}, error) { + return i.hyphenated(), nil +} + +func (u UUID) digit() string { b := createUUID() uuid := fmt.Sprintf("%x", b) return uuid } + +// Digit returns a 32 bytes UUID +func (i UUID) Digit(v reflect.Value) (interface{}, error) { + + return i.digit(), nil +} diff --git a/uuid_test.go b/uuid_test.go index e3ea26c..8b9d945 100644 --- a/uuid_test.go +++ b/uuid_test.go @@ -2,24 +2,31 @@ package faker import ( "fmt" + "reflect" "regexp" "testing" ) func TestDigit(t *testing.T) { p := GetIdentifier() - uuid := p.Digit() - if match, err := regexp.Match("^[a-zA-Z0-9]{32}$", []byte(uuid)); !match || err != nil { + uuid, err := p.Digit(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } + if match, err := regexp.Match("^[a-zA-Z0-9]{32}$", []byte(uuid.(string))); !match || err != nil { t.Errorf("Could not match the UUID format, err: %+v, match: %+v", err, match) } } func TestHyphenated(t *testing.T) { p := GetIdentifier() - uuid := p.Hyphenated() + uuid, err := p.Hyphenated(reflect.Value{}) + if err != nil { + t.Error("Expected not error, got err", err) + } exp := "[a-zA-Z 0-9]" pattern := fmt.Sprintf("^%s{8}-%s{4}-%s{4}-%s{4}-%s{12}$", exp, exp, exp, exp, exp) - if match, err := regexp.Match(pattern, []byte(uuid)); !match || err != nil { + if match, err := regexp.Match(pattern, []byte(uuid.(string))); !match || err != nil { t.Errorf("Could not match the UUID hyphenated format, err: %+v, match: %+v", err, match) }