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

Commit

Permalink
feat: add v4 initial version, with options and restructured package (#…
Browse files Browse the repository at this point in the history
…169)

* feat: add v4 initial version, with options and restructured package

* fix: move max slice to option

* fix: move min slice to option

* fix: move max str generation to option

* fix: set nil if len zero to option

* fix: set random len zero to option

* chore: move integer boundary to option

* fix: move random float to option

* fix: add integer boundaries to option

* chore: resolve linter

* feat: update WithRecursionMaxDepth & unittest (#171)

* feat: update WithRecursionMaxDepth & unittest

* style: remove unnecessary check

* chore: use variadic function for options

* chore: move to pkg directory

* fix: slice_len (#172)

* chore: update readme

Co-authored-by: OrangeWolf <[email protected]>
  • Loading branch information
bxcodec and wolf-joe authored Aug 20, 2022
1 parent 6a1323d commit a94c89d
Show file tree
Hide file tree
Showing 39 changed files with 911 additions and 887 deletions.
68 changes: 35 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,42 @@ Faker will generate you a fake data based on your Struct.
[![codecov](https://codecov.io/gh/bxcodec/faker/branch/master/graph/badge.svg)](https://codecov.io/gh/bxcodec/faker)
[![Go Report Card](https://goreportcard.com/badge/github.com/bxcodec/faker)](https://goreportcard.com/report/github.com/bxcodec/faker)
[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/bxcodec/faker/blob/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/bxcodec/faker?status.svg)](https://godoc.org/github.com/bxcodec/faker)
[![Go.Dev](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/bxcodec/faker/v3?tab=doc)
[![Go.Dev](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white)](https://pkg.go.dev/github.com/bxcodec/faker/v4?tab=doc)

## Index

* [Support](#support)
* [Getting Started](#getting-started)
* [Example](#example)
* [Limitation](#limitation)
* [Contribution](#contribution)

- [Support](#support)
- [Getting Started](#getting-started)
- [Example](#example)
- [Limitation](#limitation)
- [Contribution](#contribution)

## Support

You can file an [Issue](https://github.com/bxcodec/faker/issues/new).
See documentation in [Godoc](https://godoc.org/github.com/bxcodec/faker) or in [Go.Dev](https://pkg.go.dev/github.com/bxcodec/faker/v3?tab=doc)

See documentation in [Go.Dev](https://pkg.go.dev/github.com/bxcodec/faker/v4?tab=doc)

## Getting Started

#### Download

```shell
go get -u github.com/bxcodec/faker/v3
go get -u github.com/bxcodec/faker/v4
```

# Example

---

- Using Struct's tag:
- [basic tags: example_with_tags_test.go](/example_with_tags_test.go)
- [length and bounds: example_with_tags_lenbounds_test.go](/example_with_tags_lenbounds_test.go)
- [language: example_with_tags_lang_test.go](/example_with_tags_lang_test.go)
- [unique: example_with_tags_unique_test.go](example_with_tags_unique_test.go)
- [slice length: example_with_tags_slicelength_test.go](example_with_tags_slicelength_test.go)
- Custom Struct's tag (define your own faker data): [example_custom_faker_test.go](/example_custom_faker_test.go)
- Without struct's tag: [example_without_tag_test.go](/example_without_tag_test.go)
- Single Fake Data Function: [example_single_fake_data_test.go](/example_single_fake_data_test.go)
- Using Struct's tag:
- [basic tags: example_with_tags_test.go](/example_with_tags_test.go)
- [length and bounds: example_with_tags_lenbounds_test.go](/example_with_tags_lenbounds_test.go)
- [language: example_with_tags_lang_test.go](/example_with_tags_lang_test.go)
- [unique: example_with_tags_unique_test.go](example_with_tags_unique_test.go)
- [slice length: example_with_tags_slicelength_test.go](example_with_tags_slicelength_test.go)
- Custom Struct's tag (define your own faker data): [example_custom_faker_test.go](/example_custom_faker_test.go)
- Without struct's tag: [example_without_tag_test.go](/example_without_tag_test.go)
- Single Fake Data Function: [example_single_fake_data_test.go](/example_single_fake_data_test.go)

## DEMO

Expand All @@ -60,12 +58,15 @@ go get -u github.com/bxcodec/faker/v3
---

Bench To Generate Fake Data

#### Without Tag

```bash
BenchmarkFakerDataNOTTagged-4 500000 3049 ns/op 488 B/op 20 allocs/op
```

#### Using Tag

```bash
BenchmarkFakerDataTagged-4 100000 17470 ns/op 380 B/op 26 allocs/op
```
Expand All @@ -77,25 +78,26 @@ BenchmarkFakerDataNOTTagged-4 500000 3049 ns/op
The Struct Field must be PUBLIC.<br>
Support Only For :

* `int`, `int8`, `int16`, `int32` & `int64`
* `[]int`, `[]int8`, `[]int16`, `[]int32` & `[]int64`
* `bool` & `[]bool`
* `string` & `[]string`
* `float32`, `float64`, `[]float32` &`[]float64`
* `time.Time` & `[]time.Time`
* Nested Struct Field
- `int`, `int8`, `int16`, `int32` & `int64`
- `[]int`, `[]int8`, `[]int16`, `[]int32` & `[]int64`
- `bool` & `[]bool`
- `string` & `[]string`
- `float32`, `float64`, `[]float32` &`[]float64`
- `time.Time` & `[]time.Time`
- Nested Struct Field

## Limitation

---

Unfortunately this library has some limitation
* It does not support private fields. Make sure your structs fields you intend to generate fake data for are public, it would otherwise trigger a panic. You can however omit fields using a tag skip `faker:"-"` on your private fields.
* It does not support the `interface{}` data type. How could we generate anything without knowing its data type?
* It does not support the `map[interface{}]interface{}`, `map[any_type]interface{}` & `map[interface{}]any_type` data types. Once again, we cannot generate values for an unknown data type.
* Custom types are not fully supported. However some custom types are already supported: we are still investigating how to do this the correct way. For now, if you use `faker`, it's safer not to use any custom types in order to avoid panics.
* Some extra custom types can be supported IF AND ONLY IF extended with [AddProvider()](https://github.com/bxcodec/faker/blob/9169c33ae9926e5b8f8732909790ee20b10b736a/faker.go#L320) please see [example](example_custom_faker_test.go#L46)
* The `oneof` tag currently only supports `string`, the `int` types, and both `float32` & `float64`. Further support is coming soon (i.e. hex numbers, etc). See [example](example_with_tags_test.go#L53) for usage.

- It does not support private fields. Make sure your structs fields you intend to generate fake data for are public, it would otherwise trigger a panic. You can however omit fields using a tag skip `faker:"-"` on your private fields.
- It does not support the `interface{}` data type. How could we generate anything without knowing its data type?
- It does not support the `map[interface{}]interface{}`, `map[any_type]interface{}` & `map[interface{}]any_type` data types. Once again, we cannot generate values for an unknown data type.
- Custom types are not fully supported. However some custom types are already supported: we are still investigating how to do this the correct way. For now, if you use `faker`, it's safer not to use any custom types in order to avoid panics.
- Some extra custom types can be supported IF AND ONLY IF extended with [AddProvider()](https://github.com/bxcodec/faker/blob/9169c33ae9926e5b8f8732909790ee20b10b736a/faker.go#L320) please see [example](example_custom_faker_test.go#L46)
- The `oneof` tag currently only supports `string`, the `int` types, and both `float32` & `float64`. Further support is coming soon (i.e. hex numbers, etc). See [example](example_with_tags_test.go#L53) for usage.

## Contribution

Expand Down
24 changes: 7 additions & 17 deletions address.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,16 @@ package faker

import (
"reflect"
)

var address Addresser
"github.com/bxcodec/faker/v4/pkg/options"
)

// GetAddress returns a new Addresser interface of Address
func GetAddress() Addresser {
mu.Lock()
defer mu.Unlock()

if address == nil {
address = &Address{}
}
address := &Address{}
return address
}

// SetAddress sets custom Address
func SetAddress(net Addresser) {
address = net
}

// Addresser is logical layer for Address
type Addresser interface {
Latitude(v reflect.Value) (interface{}, error)
Expand Down Expand Up @@ -60,17 +50,17 @@ func (i Address) Longitude(v reflect.Value) (interface{}, error) {
}

// Longitude get fake longitude randomly
func Longitude() float64 {
func Longitude(opts ...options.OptionFunc) float64 {
return singleFakeData(LONGITUDE, func() interface{} {
address := Address{}
return float64(address.longitude())
}).(float64)
}, opts...).(float64)
}

// Latitude get fake latitude randomly
func Latitude() float64 {
func Latitude(opts ...options.OptionFunc) float64 {
return singleFakeData(LATITUDE, func() interface{} {
address := Address{}
return float64(address.latitude())
}).(float64)
}, opts...).(float64)
}
4 changes: 0 additions & 4 deletions address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import (
"testing"
)

func TestFakeData(t *testing.T) {
SetAddress(Address{})
}

func TestGetLongitude(t *testing.T) {
long := Longitude()
if long > 180 || long < -180 {
Expand Down
60 changes: 25 additions & 35 deletions datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"reflect"
"time"

"github.com/bxcodec/faker/v4/pkg/options"
)

var century = []string{"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX", "XXI"}
Expand Down Expand Up @@ -619,24 +621,12 @@ type DateTimer interface {
TimePeriod(v reflect.Value) (interface{}, error)
}

var date DateTimer

// GetDateTimer returns a new DateTimer interface of DateTime
func GetDateTimer() DateTimer {
mu.Lock()
defer mu.Unlock()

if date == nil {
date = &DateTime{}
}
date := &DateTime{}
return date
}

// SetDateTimer sets custom date time
func SetDateTimer(d DateTimer) {
date = d
}

// DateTime struct
type DateTime struct {
}
Expand All @@ -659,11 +649,11 @@ func (d DateTime) UnixTime(v reflect.Value) (interface{}, error) {
}

// UnixTime get unix time randomly
func UnixTime() int64 {
func UnixTime(opts ...options.OptionFunc) int64 {
return singleFakeData(UnixTimeTag, func() interface{} {
datetime := DateTime{}
return datetime.unixtime()
}).(int64)
}, opts...).(int64)
}

func (d DateTime) date() string {
Expand All @@ -676,11 +666,11 @@ func (d DateTime) Date(v reflect.Value) (interface{}, error) {
}

// Date get fake date in string randomly
func Date() string {
func Date(opts ...options.OptionFunc) string {
return singleFakeData(DATE, func() interface{} {
datetime := DateTime{}
return datetime.date()
}).(string)
}, opts...).(string)
}

func (d DateTime) time() string {
Expand All @@ -693,11 +683,11 @@ func (d DateTime) Time(v reflect.Value) (interface{}, error) {
}

// TimeString get time randomly in string format
func TimeString() string {
func TimeString(opts ...options.OptionFunc) string {
return singleFakeData(TIME, func() interface{} {
datetime := DateTime{}
return datetime.time()
}).(string)
}, opts...).(string)
}

func (d DateTime) monthName() string {
Expand All @@ -710,11 +700,11 @@ func (d DateTime) MonthName(v reflect.Value) (interface{}, error) {
}

// MonthName get month name randomly in string format
func MonthName() string {
func MonthName(opts ...options.OptionFunc) string {
return singleFakeData(MonthNameTag, func() interface{} {
datetime := DateTime{}
return datetime.monthName()
}).(string)
}, opts...).(string)
}

func (d DateTime) year() string {
Expand All @@ -727,11 +717,11 @@ func (d DateTime) Year(v reflect.Value) (interface{}, error) {
}

// YearString get year randomly in string format
func YearString() string {
func YearString(opts ...options.OptionFunc) string {
return singleFakeData(YEAR, func() interface{} {
datetime := DateTime{}
return datetime.year()
}).(string)
}, opts...).(string)
}

func (d DateTime) dayOfWeek() string {
Expand All @@ -744,11 +734,11 @@ func (d DateTime) DayOfWeek(v reflect.Value) (interface{}, error) {
}

// DayOfWeek get day of week randomly in string format
func DayOfWeek() string {
func DayOfWeek(opts ...options.OptionFunc) string {
return singleFakeData(DayOfWeekTag, func() interface{} {
datetime := DateTime{}
return datetime.dayOfWeek()
}).(string)
}, opts...).(string)
}

func (d DateTime) dayOfMonth() string {
Expand All @@ -761,11 +751,11 @@ func (d DateTime) DayOfMonth(v reflect.Value) (interface{}, error) {
}

// DayOfMonth get month randomly in string format
func DayOfMonth() string {
func DayOfMonth(opts ...options.OptionFunc) string {
return singleFakeData(DayOfMonthTag, func() interface{} {
datetime := DateTime{}
return datetime.dayOfMonth()
}).(string)
}, opts...).(string)
}

func (d DateTime) timestamp() string {
Expand All @@ -778,11 +768,11 @@ func (d DateTime) Timestamp(v reflect.Value) (interface{}, error) {
}

// Timestamp get timestamp randomly in string format: 2006-01-02 15:04:05
func Timestamp() string {
func Timestamp(opts ...options.OptionFunc) string {
return singleFakeData(TIMESTAMP, func() interface{} {
datetime := DateTime{}
return datetime.timestamp()
}).(string)
}, opts...).(string)
}

func (d DateTime) century() string {
Expand All @@ -795,11 +785,11 @@ func (d DateTime) Century(v reflect.Value) (interface{}, error) {
}

// Century get century randomly in string
func Century() string {
func Century(opts ...options.OptionFunc) string {
return singleFakeData(CENTURY, func() interface{} {
datetime := DateTime{}
return datetime.century()
}).(string)
}, opts...).(string)
}

func (d DateTime) timezone() string {
Expand All @@ -812,11 +802,11 @@ func (d DateTime) TimeZone(v reflect.Value) (interface{}, error) {
}

// Timezone get timezone randomly in string
func Timezone() string {
func Timezone(opts ...options.OptionFunc) string {
return singleFakeData(TIMEZONE, func() interface{} {
datetime := DateTime{}
return datetime.timezone()
}).(string)
}, opts...).(string)
}

func (d DateTime) period() string {
Expand All @@ -829,11 +819,11 @@ func (d DateTime) TimePeriod(v reflect.Value) (interface{}, error) {
}

// Timeperiod get timeperiod randomly in string (AM/PM)
func Timeperiod() string {
func Timeperiod(opts ...options.OptionFunc) string {
return singleFakeData(TimePeriodTag, func() interface{} {
datetime := DateTime{}
return datetime.period()
}).(string)
}, opts...).(string)
}

// RandomUnixTime is a helper function returning random Unix time
Expand Down
6 changes: 1 addition & 5 deletions datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ import (
"testing"
"time"

"github.com/bxcodec/faker/v3/support/slice"
"github.com/bxcodec/faker/v4/pkg/slice"
)

func TestSetDateTimer(t *testing.T) {
SetDateTimer(DateTime{})
}

func TestUnixTimeValueValid(t *testing.T) {
d := GetDateTimer()
var ref = struct {
Expand Down
2 changes: 1 addition & 1 deletion example_custom_faker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"
"reflect"

"github.com/bxcodec/faker/v3"
"github.com/bxcodec/faker/v4"
)

// Gondoruwo ...
Expand Down
Loading

0 comments on commit a94c89d

Please sign in to comment.