Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: change/assign faked values by implementing transformable interface #359

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

lsdch
Copy link

@lsdch lsdch commented May 26, 2024

This small feature introduces the Transformable interface which can be implemented to capture generated values and assign them as needed on a Transformable. Example use case is an option type :

type Optional[T any] struct {
	IsSet bool
	Value T
}

func (o *Optional[T]) FakeTransform(f *Faker, v any) error {
	o.IsSet = true
	o.Value = v.(T)
	return nil
}

type Container struct {
	MaybeText  Optional[string] `fake:"{sentence:5}"`
	MaybeEmail Optional[string] `fake:"{email}"`
	MaybeSlice Optional[[]string]
	MaybeAge   Optional[int] `fake:"{number:0,120}"`
}

@brianvoe brianvoe changed the base branch from master to develop May 26, 2024 16:53
@brianvoe
Copy link
Owner

I generally like the idea. I think before I would merge this in I would need a more extensive list of tests for this as to make sure we are covering all the bases like the struct tests do.

Also updating the readme after the fakeable section describing this as short and sweet as possible would help others use this feature better

Let me know your thoughts.
Thanks.

@brianvoe
Copy link
Owner

Let me know if you have any other thoughts or questions. I just want to get more coverage on this so I know we are covering the best use cases we can. Cause people do find those edge cases 😄

@lsdch
Copy link
Author

lsdch commented May 31, 2024

Hey, sorry for the late response, it has been on my stack for a while and I've actually found some time to work on this today. Asking for more test cases was a good call, as it brought some issues to the surface. The idea of Transformable appears to not be the right solution for the use-case I was thinking about, because gofakeit relies on lot on mutating reflected values, instead of sending around faked values.

I have been working on a different Recipient interface, which makes possible to define what (reflected) value should be populated with faked values.

// Recipient interface can be implemented by wrapper types to define which field
// will be set with faked values.
type Recipient interface {
	// Receptor method implementation MUST have pointer receiver,
	// e.g. func (r *R) Receptor().
	//
	// Returned value MUST have kind reflect.Pointer, or it will not be settable
	Receptor() reflect.Value
}


type Optional[T any] struct {
	IsSet bool
	Value T
}

func (o *Optional[T]) Receptor() reflect.Value {
	return reflect.ValueOf(&o.Value)
}

I will update this PR shortly, after I finished tidying things up.


I think Transformable could be an interesting feature as well, but has a different purpose from the one I originally had in mind.

// Transformable interface can be implemented to arbitrarily transform the value
// of a type after it was generated.
type Transformable interface {
	// FakeTransform method implementation must have pointer receiver,
	// so that the Transformable can be mutated.
	FakeTransform(faker *Faker) error
}

type Prefixer string

func (s *Prefixer) FakeTransform(f *Faker) error {
	*s = Prefixer(fmt.Sprintf("PREFIX.%s", *s))
	return nil
}

The idea is Transformables can be altered after generation and assignment of faked values are completed.

@brianvoe
Copy link
Owner

Ok no problem. Ill look out for your updates. Dont forget that readme, show off your best example usage so others can see how powerful what you submitted is. I gave the same story to the guy who added templates and now people can see how cool it is. and if i submit this out to a few people it might get posted like template did. https://golangweekly.com/issues/486

@lsdch
Copy link
Author

lsdch commented Jun 4, 2024

Here is the update with the new implementation for the two proposed features. Let me know if anything can be improved, thanks! 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants