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

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

Merged
merged 15 commits into from
Aug 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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