brianvoe / gofakeit

Random fake data generator written in go
MIT License
4.49k stars 263 forks source link

Inconsistency in fake data generation while changing the order of Struct's properties. #347

Closed plusiv closed 7 months ago

plusiv commented 7 months ago

Description

I'm trying to generate random data for the struct DNI which have another two nested structs (DocInfo and CitizenInfo), for an unknown reason when I put DocInfo before CitizenInfo, the CitizenInfo fake data is not being generated.

type DNI struct {
  DNI string `fake:"{ssn}"`
  Photo string `fake:"{imageurl}"`
  DocInfo DNIDocInfo
  CitizenInfo Citizen
}

type DNIDocInfo struct {
  ExpirationDate time.Time `fake:"{year}-{month}-{day}"`
}

type Citizen struct {
  Name string `fake:"{ssn}"`
  LastName string `fake:"{lastname}"`
  BirthPlace string `fake:"{city},{country} {countryabr}"`
  Nationality string `fake:"{randomstring:[Dominican,Spanish]}"`
  BirthDate time.Time `fake:"{year}-{month}-{day}"`
  Sex string `fake:"{gender}"`
  Occupation string `fake:"{jobtitle}"`
}

var dni DNI
gofakeit.Struct(&dni)
fmt.Printf("%+v", dni)

Output:

{DNI:224276379 Photo:https://picsum.photos/500/500 DocInfo:{ExpirationDate:0001-01-01 00:00:00 +0000 UTC} CitizenInfo:{Name: LastName: BirthPlace: Nationality: BirthDate:0001-01-01 00:00:00 +0000 UTC Sex: Occupation:}}%                                                                                                                               

Otherwise, putting the CitizenInfo before DocInfo both structure's fake data are generated as spected.

type DNI struct {
  DNI string `fake:"{ssn}"`
  Photo string `fake:"{imageurl}"`
  CitizenInfo Citizen // Swapped order
  DocInfo DNIDocInfo // Swapped order
}

type DNIDocInfo struct {
  ExpirationDate time.Time `fake:"{year}-{month}-{day}"`
}

type Citizen struct {
  Name string `fake:"{ssn}"`
  LastName string `fake:"{lastname}"`
  BirthPlace string `fake:"{city},{country} {countryabr}"`
  Nationality string `fake:"{randomstring:[Dominican,Spanish]}"`
  BirthDate time.Time `fake:"{year}-{month}-{day}"`
  Sex string `fake:"{gender}"`
  Occupation string `fake:"{jobtitle}"`
}

var dni DNI
gofakeit.Struct(&dni)
fmt.Printf("%+v", dni)

Output:

{DNI:107649168 Photo:https://picsum.photos/500/500 CitizenInfo:{Name:245984820 LastName:McGlynn BirthPlace:Scottsdale,Liechtenstein BT Nationality:Dominican BirthDate:0001-01-01 00:00:00 +0000 UTC Sex: Occupation:} DocInfo:{ExpirationDate:0001-01-01 00:00:00 +0000 UTC}}%                                                                                                                                

Is there any importance in the order?

brianvoe commented 7 months ago

It all comes down to how many times a function needs to run Uint64(). If you swap the order of a function that needs to run Uint64 2 times in front of a function that only needs to run it once you will alter your values.

plusiv commented 7 months ago

@brianvoe I Apologize for my ignorance on this, but, I'm not understanding the point. Where do I use a uint64 twice? I'm just trying to realize how to use it in the right way.

brianvoe commented 7 months ago

It's ok took me a sec to wrap my head around it. Take a look at an example rand source below

type Dumb struct {
    state uint64
}

// NewDumb initializes a Dumb source
func NewDumb(seed uint64) *Dumb {
    d := &Dumb{}
    d.Seed(seed)
    return d
}

func (d *Dumb) Seed(seed uint64) {
    d.state = seed
}

// Uint64 returns the next number in the sequence, incrementing the state.
func (d *Dumb) Uint64() uint64 {
    d.state += 1
    return d.state
}

So every time Uint64 is run it generates a new number.

In Gofakeit some functions may need to run Uint64() multiple times. Thus if you swap fields around, then you get an alternative output cause your previous function was given a different value then the order it was in before.

brianvoe commented 7 months ago

I just reread your initial issue and if your just having issues that one struct isnt being called it sounds like it caught an issue in the previous field. Struct returns an error so you should probably look at that.

I dont think this will work ExpirationDate time.Time fake:"{year}-{month}-{day}" that might be your issue

plusiv commented 7 months ago

I just reread your initial issue and if your just having issues that one struct isnt being called it sounds like it caught an issue in the previous field. Struct returns an error so you should probably look at that.

I dont think this will work ExpirationDate time.Time fake:"{year}-{month}-{day}" that might be your issue

You're right, I was specifying that tag in a wrong way. Fixing it worked!

Thank you so much.

brianvoe commented 7 months ago

No problem.