From 78d7d17fd5c7f48239d5f54fcbccff4f1c7fb866 Mon Sep 17 00:00:00 2001 From: "B.G.Adrian" Date: Mon, 26 Nov 2018 00:26:45 +0200 Subject: [PATCH] gometalinter: adds to travis and fixed all warnings docs/readmes updates more tests refactor templateConcurrent benchmark --- .gometalinter.json | 3 + .travis.yml | 2 + CONTRIBUTING.md | 9 +- README.md | 28 ++- TEMPLATES.md | 16 +- cmd/template-variable-generator/main.go | 13 +- data/data.go | 14 +- example/analytics/main.go | 4 +- example/analytics/producer/dispatcher.go | 10 +- example/analytics/producer/events.go | 3 +- example/analytics/producer/random.go | 2 + example/analytics/producer/user.go | 3 +- example/users/main.go | 4 +- faker/address.go | 7 +- faker/address_test.go | 10 +- faker/bool.go | 6 +- faker/datetime.go | 6 +- faker/datetime_test.go | 15 ++ faker/faker.go | 8 +- faker/hacker.go | 1 + faker/internet.go | 8 + faker/internet_test.go | 4 +- faker/misc.go | 12 +- faker/misc_test.go | 10 + faker/payment.go | 12 +- faker/payment_test.go | 18 ++ faker/person.go | 2 +- faker/templates.go | 8 +- faker/templates_test.go | 53 +++-- faker/templates_variables.go | 234 +++++++++++------------ faker/unique.go | 2 + faker/user_agent.go | 3 +- faker/words.go | 7 + faker/words_test.go | 4 +- randomizer/randwrapper_test.go | 7 +- travis.sh | 2 +- 36 files changed, 336 insertions(+), 214 deletions(-) create mode 100644 .gometalinter.json diff --git a/.gometalinter.json b/.gometalinter.json new file mode 100644 index 0000000..c163013 --- /dev/null +++ b/.gometalinter.json @@ -0,0 +1,3 @@ +{ + "Cyclo": 18 +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 49946c0..d281b5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,8 @@ matrix: env: COVERAGE=true install: +- go get github.com/alecthomas/gometalinter +- gometalinter --install --vendored-linters - make script: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef7a23e..909ae5b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,10 +12,13 @@ Fixes #issueID ## Requirements * Go (preferable the latest version) * bash-like environment with `make` -* activate the `go fmt` and `go imports` file watchers -* keep the 100% test coverage + +## All PRs must: +* maintain the 100% test coverage +* pass gometalinter without warnings +* code must be proper formatted with `go fmt` and `go imports` * each Public method must examples or tests, and a benchmark -* keep the Go 1.0 compatibility +* maintain the Go 1.0 compatibility ## Caveats The templates system is built on top of generated code. Make sure you run diff --git a/README.md b/README.md index 9c97058..fe10a28 100644 --- a/README.md +++ b/README.md @@ -103,16 +103,23 @@ go func(){ For a heavy usage in a 4 CPU env, the performance benefits of the FastFaker can be up to 10x: ``` -BenchmarkNewSafeFaker_Parallel-4 50000 30893 ns/op 0 B/op 0 allocs/op -BenchmarkNewFastFaker_Parallel-4 300000 3829 ns/op 0 B/op 0 allocs/op +go test -benchmem -bench=BenchmarkNew* github.com/bgadrian/fastfaker/faker +goos: linux +goarch: amd64 +pkg: github.com/bgadrian/fastfaker/faker +BenchmarkNewSafeFaker_Parallel-4 500000 2668 ns/op 0 B/op 0 allocs/op +BenchmarkNewFastFaker_Parallel-4 10000000 225 ns/op 0 B/op 0 allocs/op ``` ## Templates -Template is the most powerful FastFaker feature. It allows custom patterns/templates of text to be filled with over 110 random types of [data (variables)](./TEMPLATE_VARIABLES.md). +Template is the most powerful FastFaker feature. It allows custom patterns/templates (JSON, YAML, HTML, ...) of text to be filled with over 110 random types of [data (variables)](./TEMPLATE_VARIABLES.md). It can be used directly (faker.Template* methods) or via the faker.Struct fill method and `fake:` tags. ```go +//instead of: +fmt.Sprintf("I'm %s, call me at %s!", fastFaker.Name(), fastFaker.Numerify("###-###-####")) +//you can do: fastFaker.Template("I'm {name}, call me at ###-###-####!") // I'm John, call me at 152-335-8761! ``` @@ -127,13 +134,18 @@ The pseudo-data generator has its [own package](./randomizer). At its core it is ## gofakeit This library started as a fork of [gofakeit](https://github.com/brianvoe/gofakeit/), but I had different requirements from such a library, in particular performance and extensibility and could not guarantee [backward compatibility](https://github.com/brianvoe/gofakeit/issues/32). Future sync **will** be performed between the projects. -Differences between `gofakeit` and `fastfaker` (more in the [changelog](./CHANGELOG.md)) -* import path, name -* version `gofakeit` 3.x is `fastfaker` 1.x -* different documentation, new examples and tests -* non deterministic (using the same `Seed` on `fastfaker` may lead to different results, eg Name(), than the same seed with `gofakeit`) +How is FastFaker different? +* performance (up to 10x improvement) +* code quality (fixed over 50 gometalinter warnings) +* Templates +* error logger (stdErr) instead of silent fails +* new functions +* more documentation, new examples and tests * usage, instead of `gofakeit.Name()` the calls are `faker.Global.Name()` or `faker.NewFastFaker().Name()` * `fastfaker` uses the semantic version, making it compatible with go modules +* split /data and /randomizer into their own packages +* version `gofakeit` 3.x is `fastfaker` 1.x +* more in the [changelog](./CHANGELOG.md) ## Change log I try to [keep it updated here](./CHANGELOG.md). diff --git a/TEMPLATES.md b/TEMPLATES.md index 3d70fc1..ee61c12 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -1,14 +1,16 @@ -# Fast Faker Templates -Template is the most powerful FastFaker feature. It allows custom patterns/templates of text to be filled with over 110 random types of [data (variables)](./TEMPLATE_VARIABLES.md). +# FastFaker Templates -```go - fmt.Println(fastFaker.Template("Hello {name}!")) - - //Hello Jeromy Schmeler! -``` +Template is the most powerful FastFaker feature. It allows custom patterns/templates (JSON, YAML, HTML, ...) of text to be filled with over 110 random types of [data (variables)](./TEMPLATE_VARIABLES.md). It can be used directly (faker.Template* methods) or via the faker.Struct fill method and `fake:` tags. +```go +//instead of: +fmt.Sprintf("I'm %s, call me at %s!", fastFaker.Name(), fastFaker.Numerify("###-###-####")) +//you can do: +fastFaker.Template("I'm {name}, call me at ###-###-####!") // I'm John, call me at 152-335-8761! +``` + ### Faker.Template() The `Template()` function replaces: diff --git a/cmd/template-variable-generator/main.go b/cmd/template-variable-generator/main.go index 483780c..a775577 100644 --- a/cmd/template-variable-generator/main.go +++ b/cmd/template-variable-generator/main.go @@ -57,7 +57,10 @@ func main() { case string: example = res[0].String() call = fmt.Sprintf("func(f *Faker) string { return %s() }", call) - case int, int8, int16, int32, int64: + case int: + example = strconv.Itoa(int(res[0].Int())) + call = fmt.Sprintf("func(f *Faker) string { return strconv.Itoa(%s()) }", call) + case int8, int16, int32, int64: example = strconv.Itoa(int(res[0].Int())) call = fmt.Sprintf("func(f *Faker) string { return strconv.Itoa(int(%s())) }", call) case uint8, uint16, uint32, uint64: @@ -68,7 +71,7 @@ func main() { call = fmt.Sprintf("func(f *Faker) string { return strconv.FormatFloat(float64(%s()), %d, -1, 32) }", call, g) case float64: example = strconv.FormatFloat(float64(res[0].Float()), 'g', -1, 64) - call = fmt.Sprintf("func(f *Faker) string { return strconv.FormatFloat(float64(%s()), %d, -1, 64) }", call, g) + call = fmt.Sprintf("func(f *Faker) string { return strconv.FormatFloat(%s(), %d, -1, 64) }", call, g) default: continue //example = fmt.Sprintf("%v", res[0]) @@ -116,11 +119,11 @@ func init() { } func getTemplateVars() map[string]fakerer { - templateVariables := make(map[string]fakerer, 100) + vars := make(map[string]fakerer, 100) - {{range .}}templateVariables["{{.Key}}"] = {{.Call}} + {{range .}}vars["{{.Key}}"] = {{.Call}} {{end}} - return templateVariables + return vars }// Code generated by make generate DO NOT EDIT. `)) diff --git a/data/data.go b/data/data.go index ab5e016..cd21f3e 100644 --- a/data/data.go +++ b/data/data.go @@ -8,8 +8,8 @@ import ( "github.com/pkg/errors" ) -// NotFound is triggered when a category of Data is not found -const NotFound = "not found" +// ErrNotFound is triggered when a category of Data is not found +var ErrNotFound = errors.New("not found") // Intn is a part of the randomizer package. It is used to select an item from the database. type Intn interface { @@ -75,7 +75,7 @@ func intDataCheck(dataVal []string) bool { // GetRandValue from a [category, subcategory]. Returns error if not found. func GetRandValue(f Intn, dataVal []string) (string, error) { if !Check(dataVal) { - return "", errors.New(NotFound) + return "", ErrNotFound } return Data[dataVal[0]][dataVal[1]][f.Intn(len(Data[dataVal[0]][dataVal[1]]))], nil } @@ -83,7 +83,7 @@ func GetRandValue(f Intn, dataVal []string) (string, error) { // GetRandIntValue Value from a [category, subcategory]. Returns error if not found. func GetRandIntValue(f Intn, dataVal []string) (int, error) { if !intDataCheck(dataVal) { - return 0, errors.New(NotFound) + return 0, ErrNotFound } return IntData[dataVal[0]][dataVal[1]][f.Intn(len(IntData[dataVal[0]][dataVal[1]]))], nil } @@ -101,7 +101,7 @@ func Categories() map[string][]string { return types } -// DataListCache serve the same function as the global GetRandValue functionality +// SetCache serve the same function as the global GetRandValue functionality // but internally keeps a reference to a specific Category/Subcategory list // improving consecutive calls performance (no more runtime.mapaccess1_faststr) type SetCache interface { @@ -111,8 +111,8 @@ type SetCache interface { // NewDataListCache creates a new reference to a Data category set // for faster access func NewDataListCache(f Intn, dataVal []string) (SetCache, error) { - if &f == nil || Check(dataVal) == false { - return nil, errors.New(NotFound) + if &f == nil || !Check(dataVal) { + return nil, ErrNotFound } res := &simpleList{} res.randomizer = f diff --git a/example/analytics/main.go b/example/analytics/main.go index 50670c4..71e7582 100644 --- a/example/analytics/main.go +++ b/example/analytics/main.go @@ -24,10 +24,10 @@ func main() { for ev := range collector { props := ev.Properties() - userId := props[producer.KeyUserID] + userID := props[producer.KeyUserID] delete(props, producer.KeyUserID) delete(props, "event") - fmt.Printf("user %s: [%s]='%s'\n", userId, ev.Name(), props) + fmt.Printf("user %s: [%s]='%s'\n", userID, ev.Name(), props) } } diff --git a/example/analytics/producer/dispatcher.go b/example/analytics/producer/dispatcher.go index 810a086..729bc84 100644 --- a/example/analytics/producer/dispatcher.go +++ b/example/analytics/producer/dispatcher.go @@ -38,7 +38,7 @@ func (d *Dispatcher) Start(intervalSize time.Duration) { go func() { exit: for range ticker.C { - if d.running == false { + if !d.running { break exit } //must block to avoid concurrent d.online updates @@ -69,8 +69,8 @@ func (d *Dispatcher) tick() { for i := 0; i < diff; i++ { user := d.usersQueen() d.online = append(d.online, user) - userId, _ := user.Property(KeyUserID) - fmt.Printf("new user: %s\n", userId) + userID, _ := user.Property(KeyUserID) + fmt.Printf("new user: %s\n", userID) } return } @@ -78,8 +78,8 @@ func (d *Dispatcher) tick() { //remove random users for len(d.online) > usersShould { killIndex := rand.Intn(len(d.online)) - userId, _ := d.online[killIndex].Property(KeyUserID) + userID, _ := d.online[killIndex].Property(KeyUserID) d.online = append(d.online[:killIndex], d.online[killIndex+1:]...) - fmt.Printf("kill user: %s\n", userId) + fmt.Printf("kill user: %s\n", userID) } } diff --git a/example/analytics/producer/events.go b/example/analytics/producer/events.go index dd77568..63c428d 100644 --- a/example/analytics/producer/events.go +++ b/example/analytics/producer/events.go @@ -1,6 +1,7 @@ package producer -type EventGenerator func(count int) []Event +// EventGenerator is a simple functions that generate n events +type EventGenerator func(n int) []Event // Event identifies an Analytics Event type Event interface { diff --git a/example/analytics/producer/random.go b/example/analytics/producer/random.go index 80e0281..77b8481 100644 --- a/example/analytics/producer/random.go +++ b/example/analytics/producer/random.go @@ -42,10 +42,12 @@ func NewRandomEventGenerator(templateEvents []Event) *RandomEventGenerator { return gen } +// RandomEventGenerator creates random fake events type RandomEventGenerator struct { templateEvents []Event } +// NewEvents creates new fake events func (g *RandomEventGenerator) NewEvents(count int) []Event { //for now we keep our logic simple, with no correlation between the events //we just select them at random diff --git a/example/analytics/producer/user.go b/example/analytics/producer/user.go index 221fb92..18202d3 100644 --- a/example/analytics/producer/user.go +++ b/example/analytics/producer/user.go @@ -41,9 +41,8 @@ func NewSimpleUser(eventsPerMin int, evg EventGenerator, out chan<- Event, ticker := time.NewTicker(time.Millisecond * time.Duration(ms)) for { - //TODO randomize the value of each interval, //simulating lag/network issues - if u.running == false { + if !u.running { break //do not make an extra tick if it was stopped } //blocking, no 2 ticks overlap diff --git a/example/users/main.go b/example/users/main.go index f3c9eaf..5d04fdf 100644 --- a/example/users/main.go +++ b/example/users/main.go @@ -33,7 +33,7 @@ func main() { newUser := &User{} faker.Global.Struct(newUser) - asJson, _ := json.Marshal(newUser) - fmt.Println(string(asJson)) + asJSON, _ := json.Marshal(newUser) + fmt.Println(string(asJSON)) } } diff --git a/faker/address.go b/faker/address.go index a7486b9..d6ecfb0 100644 --- a/faker/address.go +++ b/faker/address.go @@ -5,6 +5,9 @@ import ( "strings" ) +// ErrRangeInvalid signals a bad input +var ErrRangeInvalid = errors.New("input range is invalid") + // AddressInfo is a struct full of address information type AddressInfo struct { Address string @@ -115,7 +118,7 @@ func (f *Faker) Latitude() float64 { // LatitudeInRange will generate a random latitude within the input range func (f *Faker) LatitudeInRange(min, max float64) (float64, error) { if min > max || min < -90 || min > 90 || max < -90 || max > 90 { - return 0, errors.New("input range is invalid") + return 0, ErrRangeInvalid } return f.Float64Range(min, max), nil } @@ -128,7 +131,7 @@ func (f *Faker) Longitude() float64 { // LongitudeInRange will generate a random longitude within the input range func (f *Faker) LongitudeInRange(min, max float64) (float64, error) { if min > max || min < -180 || min > 180 || max < -180 || max > 180 { - return 0, errors.New("input range is invalid") + return 0, ErrRangeInvalid } return f.Float64Range(min, max), nil } diff --git a/faker/address_test.go b/faker/address_test.go index 74c76da..40ab277 100644 --- a/faker/address_test.go +++ b/faker/address_test.go @@ -240,7 +240,10 @@ func ExampleFaker_LatitudeInRange() { func BenchmarkLatitudeInRange(b *testing.B) { fastFaker := NewFastFaker() for i := 0; i < b.N; i++ { - fastFaker.LatitudeInRange(-90, 90) + _, err := fastFaker.LatitudeInRange(-90, 90) + if err != nil { + b.Error(err) + } } } @@ -276,6 +279,9 @@ func ExampleFaker_LongitudeInRange() { func BenchmarkLongitudeInRange(b *testing.B) { fastFaker := NewFastFaker() for i := 0; i < b.N; i++ { - fastFaker.LongitudeInRange(-180, 180) + _, err := fastFaker.LongitudeInRange(-180, 180) + if err != nil { + b.Error(err) + } } } diff --git a/faker/bool.go b/faker/bool.go index 6945938..368329e 100644 --- a/faker/bool.go +++ b/faker/bool.go @@ -2,11 +2,7 @@ package faker // Bool will generate a random boolean value func (f *Faker) Bool() bool { - if f.Intn(2) == 1 { - return true - } - - return false + return f.Intn(2) == 1 } // BoolText will generate a random boolean value as text, "true" or "false". diff --git a/faker/datetime.go b/faker/datetime.go index 6b84665..6c0d392 100644 --- a/faker/datetime.go +++ b/faker/datetime.go @@ -89,6 +89,10 @@ func (f *Faker) TimeZoneAbv() string { // TimeZoneOffset will select a random timezone offset func (f *Faker) TimeZoneOffset() float32 { - value, _ := strconv.ParseFloat(f.getRandValue([]string{"timezone", "offset"}), 32) + value, err := strconv.ParseFloat(f.getRandValue([]string{"timezone", "offset"}), 32) + if err != nil { + errorLogger.Printf("(TimeZoneOffset) %s\n", err) + return 0 + } return float32(value) } diff --git a/faker/datetime_test.go b/faker/datetime_test.go index b0c5542..f4e63ca 100644 --- a/faker/datetime_test.go +++ b/faker/datetime_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" "time" + + "github.com/bgadrian/fastfaker/data" ) func ExampleFaker_Date() { @@ -210,3 +212,16 @@ func BenchmarkTimeZoneOffset(b *testing.B) { fastFaker.TimeZoneOffset() } } + +func TestFaker_TimeZoneOffset(t *testing.T) { + tmp := data.TimeZone["offset"] + data.TimeZone["offset"] = []string{"XXX"} + + fastFaker := NewFastFaker() + if fastFaker.TimeZoneOffset() != 0 { + t.Error("at error should return 0") + } + + data.TimeZone["offset"] = tmp + +} diff --git a/faker/faker.go b/faker/faker.go index 4f2faa8..f177927 100644 --- a/faker/faker.go +++ b/faker/faker.go @@ -1,9 +1,15 @@ package faker -import "github.com/bgadrian/fastfaker/randomizer" +import ( + "log" + "os" + + "github.com/bgadrian/fastfaker/randomizer" +) // Global is a singleton, safe for concurrency instance of a Faker. var Global *Faker +var errorLogger = log.New(os.Stderr, "[faker] ", log.LstdFlags) // Faker is the main strut that encapsulate all the package functionality. type Faker struct { diff --git a/faker/hacker.go b/faker/hacker.go index b80b024..6fcec7d 100644 --- a/faker/hacker.go +++ b/faker/hacker.go @@ -7,6 +7,7 @@ func (f *Faker) HackerPhrase() string { template := f.getRandValue([]string{"hacker", "phrase"}) //TODO improve these allocations (string > []string > string) + //nolint template cannot fail with {}, see tests result, _ := f.TemplateCustom(template, "{", "}") words := strings.Split(result, " ") words[0] = strings.Title(words[0]) diff --git a/faker/internet.go b/faker/internet.go index fbe0470..5d9e9c2 100644 --- a/faker/internet.go +++ b/faker/internet.go @@ -21,17 +21,25 @@ func (f *Faker) URL() string { buffer := bytes.Buffer{} buffer.Grow(70) if f.Bool() { + //nolint buffer never returns error buffer.WriteString("http") } else { + //nolint buffer never returns error buffer.WriteString("https") } + + //nolint buffer never returns error buffer.WriteString("://www.") + + //nolint buffer never returns error buffer.WriteString(f.DomainName()) // Slugs num := f.Number(1, 4) for i := 0; i < num; i++ { + //nolint buffer never returns error buffer.WriteRune('/') + //nolint buffer never returns error buffer.WriteString(strings.ToLower(f.BS())) } diff --git a/faker/internet_test.go b/faker/internet_test.go index 37367ef..01570e3 100644 --- a/faker/internet_test.go +++ b/faker/internet_test.go @@ -33,12 +33,12 @@ func BenchmarkDomainSuffix(b *testing.B) { } func TestFaker_URL(t *testing.T) { Global.Seed(13) - if strings.Contains(Global.URL(), "https") == false { + if !strings.Contains(Global.URL(), "https") { t.Errorf("some URLs must be https too") } Global.Seed(12) - if strings.Contains(Global.URL(), "http") == false { + if !strings.Contains(Global.URL(), "http") { t.Errorf("some URLs must be http too") } } diff --git a/faker/misc.go b/faker/misc.go index 9e8b0ac..6aa142a 100644 --- a/faker/misc.go +++ b/faker/misc.go @@ -9,15 +9,19 @@ const questionmark = '?' // Get Random Value func (f *Faker) getRandValue(dataVal []string) string { - //TODO treat the notfound case - val, _ := data.GetRandValue(f, dataVal) + val, err := data.GetRandValue(f, dataVal) + if err != nil { + return "" + } return val } // Get Random Integer Value func (f *Faker) getRandIntValue(dataVal []string) int { - //TODO treat the notfound case - val, _ := data.GetRandIntValue(f, dataVal) + val, err := data.GetRandIntValue(f, dataVal) + if err != nil { + return 0 + } return val } diff --git a/faker/misc_test.go b/faker/misc_test.go index 1492a86..ac26129 100644 --- a/faker/misc_test.go +++ b/faker/misc_test.go @@ -62,3 +62,13 @@ func TestClampInt(t *testing.T) { t.Errorf("failed for 1, 10, 20") } } + +func TestGeRandErrors(t *testing.T) { + fastFaker := NewFastFaker() + if fastFaker.getRandIntValue([]string{"XXX", "XXX"}) != 0 { + t.Error("should return 0 when category not found") + } + if fastFaker.getRandValue([]string{"XXX", "XXX"}) != "" { + t.Error("should return '' when category not found") + } +} diff --git a/faker/payment.go b/faker/payment.go index caf5f0d..2632353 100644 --- a/faker/payment.go +++ b/faker/payment.go @@ -30,7 +30,11 @@ func (f *Faker) CreditCardType() string { // CreditCardNumber will generate a random credit card number int func (f *Faker) CreditCardNumber() int { - integer, _ := strconv.Atoi(f.replaceWithNumbers(f.getRandValue([]string{"payment", "number"}))) + integer, err := strconv.Atoi(f.replaceWithNumbers(f.getRandValue([]string{"payment", "number"}))) + if err != nil { + errorLogger.Printf("(CreditCardNumber) %s\n", err) + return 0 + } return integer } @@ -43,7 +47,11 @@ func (f *Faker) CreditCardNumberLuhn() int { break } } - integer, _ := strconv.Atoi(cc) + integer, err := strconv.Atoi(cc) + if err != nil { + errorLogger.Printf("(CreditCardNumberLuhn) %s\n", err) + return 0 + } return integer } diff --git a/faker/payment_test.go b/faker/payment_test.go index 6ead5a8..03c8ef3 100644 --- a/faker/payment_test.go +++ b/faker/payment_test.go @@ -4,6 +4,8 @@ import ( "fmt" "strconv" "testing" + + "github.com/bgadrian/fastfaker/data" ) func ExampleFaker_CreditCard() { @@ -107,3 +109,19 @@ func BenchmarkCreditCardCvv(b *testing.B) { fastFaker.CreditCardCvv() } } + +func TestFaker_CreditCardInvalidDB(t *testing.T) { + tmp := data.Payment["number"] + data.Payment["number"] = []string{"XXX"} + + fastFaker := NewFastFaker() + if fastFaker.CreditCardNumber() != 0 { + t.Error("at error CreditCardNumber should return 0") + } + + if fastFaker.CreditCardNumberLuhn() != 0 { + t.Error("at error CreditCardNumberLuhn should return 0") + } + + data.Payment["number"] = tmp +} diff --git a/faker/person.go b/faker/person.go index 2e9a5dc..42d9f76 100644 --- a/faker/person.go +++ b/faker/person.go @@ -9,7 +9,7 @@ func (f *Faker) SSN() string { // Gender will generate a random gender string "male" or "female" func (f *Faker) Gender() string { - if f.Bool() == true { + if f.Bool() { return "male" } diff --git a/faker/templates.go b/faker/templates.go index 81d575e..92a5e94 100644 --- a/faker/templates.go +++ b/faker/templates.go @@ -23,6 +23,7 @@ func (f *Faker) Template(pattern string) string { pattern = f.Numerify(pattern) pattern = f.Lexify(pattern) + //nolint template cannot fail with {}, see tests result, _ := f.TemplateCustom(pattern, "{", "}") return result } @@ -82,7 +83,7 @@ func (f *Faker) TemplateCustom(template, delimStart, delimEnd string) (string, e } for _, r := range delimStart + delimEnd { - if strings.ContainsRune(TemplateAllowedDelimiters, r) == false { + if !strings.ContainsRune(TemplateAllowedDelimiters, r) { return template, fmt.Errorf("delimiters error, supported ones are: '%s'", TemplateAllowedDelimiters) } } @@ -128,7 +129,7 @@ func (f *Faker) TemplateCustom(template, delimStart, delimEnd string) (string, e variable := strings.ToLower(variableWithDelim[sizeDelimStart : len(variableWithDelim)-sizeDelimEnd]) pos.variableFunc, exists = templateVariables[variable] - if exists == false { + if !exists { //the variable does not exists templateKeyPosPool.Put(pos) continue @@ -162,10 +163,13 @@ func (f *Faker) TemplateCustom(template, delimStart, delimEnd string) (string, e var lastEnd int //we go trough each byte and replace the variable with a value for _, posToReplace := range toReplace { + //nolint buffer never returns error buff.Write(templateAsByte[lastEnd:posToReplace.start]) buff.WriteString(posToReplace.variableFunc(f)) + //nolint buffer never returns error lastEnd = posToReplace.end } + //nolint buffer never returns error buff.Write(templateAsByte[lastEnd:]) result := buff.String() diff --git a/faker/templates_test.go b/faker/templates_test.go index fd60839..b7bf605 100644 --- a/faker/templates_test.go +++ b/faker/templates_test.go @@ -3,7 +3,6 @@ package faker import ( "fmt" "strings" - "sync" "testing" ) @@ -157,7 +156,7 @@ func ExampleFaker_Template() { //Hello Kim Steuber! } -func ExampleFaker_TemplateJSON() { +func ExampleFaker_Template_json() { template := `{name:"{name}", age: {digit}, confirmed: {booltext}}` fastFaker := NewFastFaker() // not concurrent safe, see NewSafeFaker() @@ -167,7 +166,7 @@ func ExampleFaker_TemplateJSON() { // Output:{name:"Jeromy Schmeler", age: 8, confirmed: false} } -func ExampleFaker_TemplateHTML() { +func ExampleFaker_Template_html() { template := ` } -func ExampleFaker_TemplateYAML() { +func ExampleFaker_Template_yaml() { template := ` invoice: ###### date: {year}-{month}-{day} @@ -223,7 +222,7 @@ total: {uint16}.##` //total: 49128.82 } -func TestFaker_TemplateVariables(t *testing.T) { +func TestFaker_Template_variables(t *testing.T) { fastFaker := NewFastFaker() // not concurrent safe, see NewSafeFaker() for variable := range templateVariables { @@ -246,31 +245,31 @@ func BenchmarkFaker_TemplateCustom(b *testing.B) { template := "😀o😀{name} {word} {uint8}" fastFaker := NewFastFaker() for i := 0; i < b.N; i++ { - fastFaker.TemplateCustom(template, "{", "}") + _, err := fastFaker.TemplateCustom(template, "{", "}") + if err != nil { + b.Error(err) + } } } -func BenchmarkFaker_TemplateCustomConcurrent1(b *testing.B) { - template1 := "😀o😀{name} {word} {uint8}" - template2 := "😀{name} {word} {city} {carmaker} {uint8} {firstname} {uint8}" - wg := sync.WaitGroup{} +func BenchmarkFaker_TemplateCustomConcurrent(b *testing.B) { + templates := []string{"😀o😀{name} {word} {uint8}", + "😀{name} {word} {city} {carmaker} {uint8} {firstname} {uint8}"} + var err error - f := func(temp string) { - fastFaker := NewFastFaker() - for i := 0; i < 50; i++ { - fastFaker.TemplateCustom(temp, "{", "}") - } - wg.Done() - } + b.RunParallel(func(pb *testing.PB) { + //each thread has its own faker + fast := NewFastFaker() - for i := 0; i < b.N; i++ { - wg.Add(6) - go f(template1) - go f(template2) - go f(template1) - go f(template2) - go f(template1) - go f(template2) - wg.Wait() - } + for pb.Next() { + _, err = fast.TemplateCustom(templates[0], "{", "}") + if err != nil { + b.Error(err) + } + _, err = fast.TemplateCustom(templates[1], "{", "}") + if err != nil { + b.Error(err) + } + } + }) } diff --git a/faker/templates_variables.go b/faker/templates_variables.go index 4ab8c46..11a4e43 100644 --- a/faker/templates_variables.go +++ b/faker/templates_variables.go @@ -15,124 +15,124 @@ func init() { } func getTemplateVars() map[string]fakerer { - templateVariables := make(map[string]fakerer, 100) + vars := make(map[string]fakerer, 100) - templateVariables["avatarurl"] = func(f *Faker) string { return f.AvatarURL() } - templateVariables["beeralcohol"] = func(f *Faker) string { return f.BeerAlcohol() } - templateVariables["beerblg"] = func(f *Faker) string { return f.BeerBlg() } - templateVariables["beerhop"] = func(f *Faker) string { return f.BeerHop() } - templateVariables["beeribu"] = func(f *Faker) string { return f.BeerIbu() } - templateVariables["beermalt"] = func(f *Faker) string { return f.BeerMalt() } - templateVariables["beername"] = func(f *Faker) string { return f.BeerName() } - templateVariables["beerstyle"] = func(f *Faker) string { return f.BeerStyle() } - templateVariables["beeryeast"] = func(f *Faker) string { return f.BeerYeast() } - templateVariables["binary"] = func(f *Faker) string { return f.Binary() } - templateVariables["booltext"] = func(f *Faker) string { return f.BoolText() } - templateVariables["browser"] = func(f *Faker) string { return f.Browser() } - templateVariables["bs"] = func(f *Faker) string { return f.BS() } - templateVariables["buzzword"] = func(f *Faker) string { return f.BuzzWord() } - templateVariables["carmaker"] = func(f *Faker) string { return f.CarMaker() } - templateVariables["carmodel"] = func(f *Faker) string { return f.CarModel() } - templateVariables["chromeuseragent"] = func(f *Faker) string { return f.ChromeUserAgent() } - templateVariables["city"] = func(f *Faker) string { return f.City() } - templateVariables["color"] = func(f *Faker) string { return f.Color() } - templateVariables["company"] = func(f *Faker) string { return f.Company() } - templateVariables["companysuffix"] = func(f *Faker) string { return f.CompanySuffix() } - templateVariables["country"] = func(f *Faker) string { return f.Country() } - templateVariables["countryabr"] = func(f *Faker) string { return f.CountryAbr() } - templateVariables["creditcardcvv"] = func(f *Faker) string { return f.CreditCardCvv() } - templateVariables["creditcardexp"] = func(f *Faker) string { return f.CreditCardExp() } - templateVariables["creditcardnumber"] = func(f *Faker) string { return strconv.Itoa(int(f.CreditCardNumber())) } - templateVariables["creditcardnumberluhn"] = func(f *Faker) string { return strconv.Itoa(int(f.CreditCardNumberLuhn())) } - templateVariables["creditcardtype"] = func(f *Faker) string { return f.CreditCardType() } - templateVariables["currencylong"] = func(f *Faker) string { return f.CurrencyLong() } - templateVariables["currencyshort"] = func(f *Faker) string { return f.CurrencyShort() } - templateVariables["datecurrentyearstr"] = func(f *Faker) string { return f.DateCurrentYearStr() } - templateVariables["datestr"] = func(f *Faker) string { return f.DateStr() } - templateVariables["day"] = func(f *Faker) string { return strconv.Itoa(int(f.Day())) } - templateVariables["digit"] = func(f *Faker) string { return f.Digit() } - templateVariables["domainname"] = func(f *Faker) string { return f.DomainName() } - templateVariables["domainsuffix"] = func(f *Faker) string { return f.DomainSuffix() } - templateVariables["email"] = func(f *Faker) string { return f.Email() } - templateVariables["extension"] = func(f *Faker) string { return f.Extension() } - templateVariables["firefoxuseragent"] = func(f *Faker) string { return f.FirefoxUserAgent() } - templateVariables["firstname"] = func(f *Faker) string { return f.FirstName() } - templateVariables["float32"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Float32()), 103, -1, 32) } - templateVariables["float64"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Float64()), 103, -1, 64) } - templateVariables["float64unary"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Float64Unary()), 103, -1, 64) } - templateVariables["fueltype"] = func(f *Faker) string { return f.FuelType() } - templateVariables["gender"] = func(f *Faker) string { return f.Gender() } - templateVariables["hackerabbreviation"] = func(f *Faker) string { return f.HackerAbbreviation() } - templateVariables["hackeradjective"] = func(f *Faker) string { return f.HackerAdjective() } - templateVariables["hackeringverb"] = func(f *Faker) string { return f.HackerIngverb() } - templateVariables["hackernoun"] = func(f *Faker) string { return f.HackerNoun() } - templateVariables["hackerphrase"] = func(f *Faker) string { return f.HackerPhrase() } - templateVariables["hackerverb"] = func(f *Faker) string { return f.HackerVerb() } - templateVariables["hexcolor"] = func(f *Faker) string { return f.HexColor() } - templateVariables["hipsterparagraphavg"] = func(f *Faker) string { return f.HipsterParagraphAvg() } - templateVariables["hipstersentenceavg"] = func(f *Faker) string { return f.HipsterSentenceAvg() } - templateVariables["hipsterword"] = func(f *Faker) string { return f.HipsterWord() } - templateVariables["hour"] = func(f *Faker) string { return strconv.Itoa(int(f.Hour())) } - templateVariables["httpmethod"] = func(f *Faker) string { return f.HTTPMethod() } - templateVariables["int16"] = func(f *Faker) string { return strconv.Itoa(int(f.Int16())) } - templateVariables["int32"] = func(f *Faker) string { return strconv.Itoa(int(f.Int32())) } - templateVariables["int64"] = func(f *Faker) string { return strconv.Itoa(int(f.Int64())) } - templateVariables["int64positive"] = func(f *Faker) string { return strconv.Itoa(int(f.Int64Positive())) } - templateVariables["int8"] = func(f *Faker) string { return strconv.Itoa(int(f.Int8())) } - templateVariables["ipv4address"] = func(f *Faker) string { return f.IPv4Address() } - templateVariables["ipv6address"] = func(f *Faker) string { return f.IPv6Address() } - templateVariables["jobdescriptor"] = func(f *Faker) string { return f.JobDescriptor() } - templateVariables["joblevel"] = func(f *Faker) string { return f.JobLevel() } - templateVariables["jobtitle"] = func(f *Faker) string { return f.JobTitle() } - templateVariables["lastname"] = func(f *Faker) string { return f.LastName() } - templateVariables["latitude"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Latitude()), 103, -1, 64) } - templateVariables["letter"] = func(f *Faker) string { return f.Letter() } - templateVariables["longitude"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Longitude()), 103, -1, 64) } - templateVariables["mimetype"] = func(f *Faker) string { return f.MimeType() } - templateVariables["minute"] = func(f *Faker) string { return strconv.Itoa(int(f.Minute())) } - templateVariables["month"] = func(f *Faker) string { return f.Month() } - templateVariables["name"] = func(f *Faker) string { return f.Name() } - templateVariables["nameprefix"] = func(f *Faker) string { return f.NamePrefix() } - templateVariables["namesuffix"] = func(f *Faker) string { return f.NameSuffix() } - templateVariables["nanosecond"] = func(f *Faker) string { return strconv.Itoa(int(f.NanoSecond())) } - templateVariables["operauseragent"] = func(f *Faker) string { return f.OperaUserAgent() } - templateVariables["paragraphavg"] = func(f *Faker) string { return f.ParagraphAvg() } - templateVariables["passwordfull"] = func(f *Faker) string { return f.PasswordFull() } - templateVariables["phone"] = func(f *Faker) string { return f.Phone() } - templateVariables["phoneformatted"] = func(f *Faker) string { return f.PhoneFormatted() } - templateVariables["safariuseragent"] = func(f *Faker) string { return f.SafariUserAgent() } - templateVariables["safecolor"] = func(f *Faker) string { return f.SafeColor() } - templateVariables["second"] = func(f *Faker) string { return strconv.Itoa(int(f.Second())) } - templateVariables["sentenceavg"] = func(f *Faker) string { return f.SentenceAvg() } - templateVariables["simplestatuscode"] = func(f *Faker) string { return strconv.Itoa(int(f.SimpleStatusCode())) } - templateVariables["ssn"] = func(f *Faker) string { return f.SSN() } - templateVariables["state"] = func(f *Faker) string { return f.State() } - templateVariables["stateabr"] = func(f *Faker) string { return f.StateAbr() } - templateVariables["statuscode"] = func(f *Faker) string { return strconv.Itoa(int(f.StatusCode())) } - templateVariables["street"] = func(f *Faker) string { return f.Street() } - templateVariables["streetname"] = func(f *Faker) string { return f.StreetName() } - templateVariables["streetnumber"] = func(f *Faker) string { return f.StreetNumber() } - templateVariables["streetprefix"] = func(f *Faker) string { return f.StreetPrefix() } - templateVariables["streetsuffix"] = func(f *Faker) string { return f.StreetSuffix() } - templateVariables["timezone"] = func(f *Faker) string { return f.TimeZone() } - templateVariables["timezoneabv"] = func(f *Faker) string { return f.TimeZoneAbv() } - templateVariables["timezonefull"] = func(f *Faker) string { return f.TimeZoneFull() } - templateVariables["timezoneoffset"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.TimeZoneOffset()), 103, -1, 32) } - templateVariables["transmissiongeartype"] = func(f *Faker) string { return f.TransmissionGearType() } - templateVariables["uint16"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint16())) } - templateVariables["uint32"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint32())) } - templateVariables["uint64"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint64())) } - templateVariables["uint8"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint8())) } - templateVariables["url"] = func(f *Faker) string { return f.URL() } - templateVariables["useragent"] = func(f *Faker) string { return f.UserAgent() } - templateVariables["username"] = func(f *Faker) string { return f.Username() } - templateVariables["uuid"] = func(f *Faker) string { return f.UUID() } - templateVariables["vehicletype"] = func(f *Faker) string { return f.VehicleType() } - templateVariables["weekday"] = func(f *Faker) string { return f.WeekDay() } - templateVariables["word"] = func(f *Faker) string { return f.Word() } - templateVariables["year"] = func(f *Faker) string { return strconv.Itoa(int(f.Year())) } - templateVariables["zip"] = func(f *Faker) string { return f.Zip() } + vars["avatarurl"] = func(f *Faker) string { return f.AvatarURL() } + vars["beeralcohol"] = func(f *Faker) string { return f.BeerAlcohol() } + vars["beerblg"] = func(f *Faker) string { return f.BeerBlg() } + vars["beerhop"] = func(f *Faker) string { return f.BeerHop() } + vars["beeribu"] = func(f *Faker) string { return f.BeerIbu() } + vars["beermalt"] = func(f *Faker) string { return f.BeerMalt() } + vars["beername"] = func(f *Faker) string { return f.BeerName() } + vars["beerstyle"] = func(f *Faker) string { return f.BeerStyle() } + vars["beeryeast"] = func(f *Faker) string { return f.BeerYeast() } + vars["binary"] = func(f *Faker) string { return f.Binary() } + vars["booltext"] = func(f *Faker) string { return f.BoolText() } + vars["browser"] = func(f *Faker) string { return f.Browser() } + vars["bs"] = func(f *Faker) string { return f.BS() } + vars["buzzword"] = func(f *Faker) string { return f.BuzzWord() } + vars["carmaker"] = func(f *Faker) string { return f.CarMaker() } + vars["carmodel"] = func(f *Faker) string { return f.CarModel() } + vars["chromeuseragent"] = func(f *Faker) string { return f.ChromeUserAgent() } + vars["city"] = func(f *Faker) string { return f.City() } + vars["color"] = func(f *Faker) string { return f.Color() } + vars["company"] = func(f *Faker) string { return f.Company() } + vars["companysuffix"] = func(f *Faker) string { return f.CompanySuffix() } + vars["country"] = func(f *Faker) string { return f.Country() } + vars["countryabr"] = func(f *Faker) string { return f.CountryAbr() } + vars["creditcardcvv"] = func(f *Faker) string { return f.CreditCardCvv() } + vars["creditcardexp"] = func(f *Faker) string { return f.CreditCardExp() } + vars["creditcardnumber"] = func(f *Faker) string { return strconv.Itoa(f.CreditCardNumber()) } + vars["creditcardnumberluhn"] = func(f *Faker) string { return strconv.Itoa(f.CreditCardNumberLuhn()) } + vars["creditcardtype"] = func(f *Faker) string { return f.CreditCardType() } + vars["currencylong"] = func(f *Faker) string { return f.CurrencyLong() } + vars["currencyshort"] = func(f *Faker) string { return f.CurrencyShort() } + vars["datecurrentyearstr"] = func(f *Faker) string { return f.DateCurrentYearStr() } + vars["datestr"] = func(f *Faker) string { return f.DateStr() } + vars["day"] = func(f *Faker) string { return strconv.Itoa(f.Day()) } + vars["digit"] = func(f *Faker) string { return f.Digit() } + vars["domainname"] = func(f *Faker) string { return f.DomainName() } + vars["domainsuffix"] = func(f *Faker) string { return f.DomainSuffix() } + vars["email"] = func(f *Faker) string { return f.Email() } + vars["extension"] = func(f *Faker) string { return f.Extension() } + vars["firefoxuseragent"] = func(f *Faker) string { return f.FirefoxUserAgent() } + vars["firstname"] = func(f *Faker) string { return f.FirstName() } + vars["float32"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.Float32()), 103, -1, 32) } + vars["float64"] = func(f *Faker) string { return strconv.FormatFloat(f.Float64(), 103, -1, 64) } + vars["float64unary"] = func(f *Faker) string { return strconv.FormatFloat(f.Float64Unary(), 103, -1, 64) } + vars["fueltype"] = func(f *Faker) string { return f.FuelType() } + vars["gender"] = func(f *Faker) string { return f.Gender() } + vars["hackerabbreviation"] = func(f *Faker) string { return f.HackerAbbreviation() } + vars["hackeradjective"] = func(f *Faker) string { return f.HackerAdjective() } + vars["hackeringverb"] = func(f *Faker) string { return f.HackerIngverb() } + vars["hackernoun"] = func(f *Faker) string { return f.HackerNoun() } + vars["hackerphrase"] = func(f *Faker) string { return f.HackerPhrase() } + vars["hackerverb"] = func(f *Faker) string { return f.HackerVerb() } + vars["hexcolor"] = func(f *Faker) string { return f.HexColor() } + vars["hipsterparagraphavg"] = func(f *Faker) string { return f.HipsterParagraphAvg() } + vars["hipstersentenceavg"] = func(f *Faker) string { return f.HipsterSentenceAvg() } + vars["hipsterword"] = func(f *Faker) string { return f.HipsterWord() } + vars["hour"] = func(f *Faker) string { return strconv.Itoa(f.Hour()) } + vars["httpmethod"] = func(f *Faker) string { return f.HTTPMethod() } + vars["int16"] = func(f *Faker) string { return strconv.Itoa(int(f.Int16())) } + vars["int32"] = func(f *Faker) string { return strconv.Itoa(int(f.Int32())) } + vars["int64"] = func(f *Faker) string { return strconv.Itoa(int(f.Int64())) } + vars["int64positive"] = func(f *Faker) string { return strconv.Itoa(int(f.Int64Positive())) } + vars["int8"] = func(f *Faker) string { return strconv.Itoa(int(f.Int8())) } + vars["ipv4address"] = func(f *Faker) string { return f.IPv4Address() } + vars["ipv6address"] = func(f *Faker) string { return f.IPv6Address() } + vars["jobdescriptor"] = func(f *Faker) string { return f.JobDescriptor() } + vars["joblevel"] = func(f *Faker) string { return f.JobLevel() } + vars["jobtitle"] = func(f *Faker) string { return f.JobTitle() } + vars["lastname"] = func(f *Faker) string { return f.LastName() } + vars["latitude"] = func(f *Faker) string { return strconv.FormatFloat(f.Latitude(), 103, -1, 64) } + vars["letter"] = func(f *Faker) string { return f.Letter() } + vars["longitude"] = func(f *Faker) string { return strconv.FormatFloat(f.Longitude(), 103, -1, 64) } + vars["mimetype"] = func(f *Faker) string { return f.MimeType() } + vars["minute"] = func(f *Faker) string { return strconv.Itoa(f.Minute()) } + vars["month"] = func(f *Faker) string { return f.Month() } + vars["name"] = func(f *Faker) string { return f.Name() } + vars["nameprefix"] = func(f *Faker) string { return f.NamePrefix() } + vars["namesuffix"] = func(f *Faker) string { return f.NameSuffix() } + vars["nanosecond"] = func(f *Faker) string { return strconv.Itoa(f.NanoSecond()) } + vars["operauseragent"] = func(f *Faker) string { return f.OperaUserAgent() } + vars["paragraphavg"] = func(f *Faker) string { return f.ParagraphAvg() } + vars["passwordfull"] = func(f *Faker) string { return f.PasswordFull() } + vars["phone"] = func(f *Faker) string { return f.Phone() } + vars["phoneformatted"] = func(f *Faker) string { return f.PhoneFormatted() } + vars["safariuseragent"] = func(f *Faker) string { return f.SafariUserAgent() } + vars["safecolor"] = func(f *Faker) string { return f.SafeColor() } + vars["second"] = func(f *Faker) string { return strconv.Itoa(f.Second()) } + vars["sentenceavg"] = func(f *Faker) string { return f.SentenceAvg() } + vars["simplestatuscode"] = func(f *Faker) string { return strconv.Itoa(f.SimpleStatusCode()) } + vars["ssn"] = func(f *Faker) string { return f.SSN() } + vars["state"] = func(f *Faker) string { return f.State() } + vars["stateabr"] = func(f *Faker) string { return f.StateAbr() } + vars["statuscode"] = func(f *Faker) string { return strconv.Itoa(f.StatusCode()) } + vars["street"] = func(f *Faker) string { return f.Street() } + vars["streetname"] = func(f *Faker) string { return f.StreetName() } + vars["streetnumber"] = func(f *Faker) string { return f.StreetNumber() } + vars["streetprefix"] = func(f *Faker) string { return f.StreetPrefix() } + vars["streetsuffix"] = func(f *Faker) string { return f.StreetSuffix() } + vars["timezone"] = func(f *Faker) string { return f.TimeZone() } + vars["timezoneabv"] = func(f *Faker) string { return f.TimeZoneAbv() } + vars["timezonefull"] = func(f *Faker) string { return f.TimeZoneFull() } + vars["timezoneoffset"] = func(f *Faker) string { return strconv.FormatFloat(float64(f.TimeZoneOffset()), 103, -1, 32) } + vars["transmissiongeartype"] = func(f *Faker) string { return f.TransmissionGearType() } + vars["uint16"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint16())) } + vars["uint32"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint32())) } + vars["uint64"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint64())) } + vars["uint8"] = func(f *Faker) string { return strconv.Itoa(int(f.Uint8())) } + vars["url"] = func(f *Faker) string { return f.URL() } + vars["useragent"] = func(f *Faker) string { return f.UserAgent() } + vars["username"] = func(f *Faker) string { return f.Username() } + vars["uuid"] = func(f *Faker) string { return f.UUID() } + vars["vehicletype"] = func(f *Faker) string { return f.VehicleType() } + vars["weekday"] = func(f *Faker) string { return f.WeekDay() } + vars["word"] = func(f *Faker) string { return f.Word() } + vars["year"] = func(f *Faker) string { return strconv.Itoa(f.Year()) } + vars["zip"] = func(f *Faker) string { return f.Zip() } - return templateVariables + return vars }// Code generated by make generate DO NOT EDIT. diff --git a/faker/unique.go b/faker/unique.go index f647093..e0b0b38 100644 --- a/faker/unique.go +++ b/faker/unique.go @@ -10,6 +10,8 @@ func (f *Faker) UUID() string { version := byte(4) uuid := make([]byte, 16) + //nolint it always return a nil error + //noinspection GoUnhandledErrorResult f.Read(uuid) // Set version diff --git a/faker/user_agent.go b/faker/user_agent.go index 36ff70f..aa473dd 100644 --- a/faker/user_agent.go +++ b/faker/user_agent.go @@ -2,11 +2,12 @@ package faker import "strconv" +// Browser will generate a random browser name func (f *Faker) Browser() string { return f.getRandValue([]string{"internet", "browser"}) } -// UserAgent will generate a random broswer user agent +// UserAgent will generate a random browser user agent func (f *Faker) UserAgent() string { randNum := f.Number(0, 4) switch randNum { diff --git a/faker/words.go b/faker/words.go index 2fff591..8edd948 100644 --- a/faker/words.go +++ b/faker/words.go @@ -25,6 +25,7 @@ func (f *Faker) Word() string { func (f *Faker) Sentence(wordCount int) string { wordSetCache, err := data.NewDataListCache(f, []string{"lorem", "word"}) if err != nil { + errorLogger.Printf("(Sentence) %s\n", err) return "" } return f.sentence(wordCount, wordSetCache, nil).String() @@ -49,6 +50,7 @@ func (f *Faker) ParagraphAvg() string { func (f *Faker) Paragraph(paragraphCount int, sentenceCount int, wordCount int, separator string) string { wordSetCache, err := data.NewDataListCache(f, []string{"lorem", "word"}) if err != nil { + errorLogger.Printf("(Paragraph) %s\n", err) return "" } return f.paragraphGenerator( @@ -73,11 +75,14 @@ func (f *Faker) sentence(wordCount int, word data.SetCache, sentence *bytes.Buff runes[0] = unicode.ToTitle(runes[0]) word = string(runes) } + //nolint buffer always return nil error sentence.WriteString(word) if i < wordCount-1 { + //nolint buffer always return nil error sentence.WriteRune(' ') } } + //nolint buffer always return nil error sentence.WriteRune('.') return sentence } @@ -97,11 +102,13 @@ func (f *Faker) paragraphGenerator(opts paragrapOptions, word data.SetCache) str for e := 0; e < opts.sentenceCount; e++ { f.sentence(opts.wordCount, word, paragraphs) if e < opts.sentenceCount-1 { + //nolint buffer always return nil error paragraphs.WriteRune(wordSeparator) } } if i < opts.paragraphCount-1 { + //nolint buffer always return nil error paragraphs.WriteString(opts.separator) } } diff --git a/faker/words_test.go b/faker/words_test.go index 49e50b6..e09431b 100644 --- a/faker/words_test.go +++ b/faker/words_test.go @@ -63,14 +63,14 @@ func ExampleFaker_ParagraphAvg() { //Id unde et porro est repudiandae omnis beatae iusto pariatur quia sed laboriosam voluptate earum dolores facilis aspernatur. Quam aperiam et nihil explicabo voluptates officia ad porro animi officiis et quam in voluptatem eveniet temporibus fuga. } -func TestSentence(t *testing.T) { +func TestFaker_Sentence(t *testing.T) { for _, count := range []int{-100, -1, 0} { if Global.Sentence(count) != "" { t.Errorf("result should be blank for %d words", count) } } } -func TestParagraph(t *testing.T) { +func TestFaker_Paragraph(t *testing.T) { for _, count := range []struct{ parag, sent, words int }{ {1, 1, 0}, {1, 0, 1}, diff --git a/randomizer/randwrapper_test.go b/randomizer/randwrapper_test.go index 5a599c5..257ed17 100644 --- a/randomizer/randwrapper_test.go +++ b/randomizer/randwrapper_test.go @@ -154,7 +154,7 @@ func TestNewSafeFaker_Deadlocks(t *testing.T) { safe := NewRandWrapper(true, nil) wg.Add(threads) - for t := 0; t < threads; t++ { + for test := 0; test < threads; test++ { go func() { for i := 0; i < steps; i++ { as64 := int64(i + 10000) @@ -169,7 +169,10 @@ func TestNewSafeFaker_Deadlocks(t *testing.T) { safe.Float64Range(-23.2, 452.2) safe.ShuffleInts([]int{3, 2, 1}) safe.Intn(i + 102) - safe.Read([]byte{0, 0, 0}) + _, err := safe.Read([]byte{0, 0, 0}) + if err != nil { + t.Error(err) + } safe.Float64Unary() } wg.Done() diff --git a/travis.sh b/travis.sh index 7a3f19f..08afaa5 100755 --- a/travis.sh +++ b/travis.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash #go 1.0 fail: cannot use test profile flag with multiple packages -[[ -v COVERAGE ]] && go test -coverprofile=coverage.txt -covermode=atomic ./... || go test ./... \ No newline at end of file +[[ -v COVERAGE ]] && go test -coverprofile=coverage.txt -covermode=atomic ./... && gometalinter ./... || go test ./... \ No newline at end of file