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

[Modifiers] Helper methods to use our custom generators #155

Merged
merged 16 commits into from
Jan 19, 2022

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Dec 19, 2020

This will add real methods to use our custom generators. They are described in https://github.com/Nyholm/next-faker#modifiers

@localheinz
Copy link
Member

localheinz commented Dec 20, 2020

@Nyholm

Probably best to rebase on top of main!

*
* @return self The UniqueGenerator is a proxy
*/
public function withUnique()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function withUnique()
public function withUnique(): self

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is technically not true. (And also why psalm is complaining).

The UniqueGenerator and other generators will implement the magic method __call(). They can be used and treated as they are a Generator but they are not really.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we agreed to do away with magic?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everywhere but the proxy generators. Im not sure how to implement the Modifiers without them proxying calls to Generator.

I would be super happy to get a suggestion.

Copy link
Member

@bram-pkg bram-pkg Feb 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the UniqueGenerator just an implementation of a generator, hence returning self would be correct, since it extends generator?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No not really. It is a proxy. It does not extend.

src/Faker/Generator.php Outdated Show resolved Hide resolved
src/Faker/Generator.php Outdated Show resolved Hide resolved

public function __construct()
{
$this->uniqueGenerator = new UniqueGenerator($this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each Generator instance has a UniqueGenerator. So I can run:

$faker->name(); // Might be 'Alice'
$faker->withUnique()->name(); // Might be 'Bob'
$faker->name(); // Might be 'Alice' again
$faker->withUnique()->name(); // Might be anything but 'Bob'

If we were about to create a new UniqueGenerator each time we called withUnique(), we could not guarantee it's uniqueness. Unless we used static variables, but then the uniqueness would be global and not specific to a instance of the Generator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of reimplementing the behaviour here, what do you think about moving methods from Faker\Provider\Base to Faker\Generator one by one, guided by tests?

Also see #233.

@krsriq
Copy link

krsriq commented Dec 22, 2020

Maybe I have overlooked something, but I think there's a bug here now when calling withMaybe() with an extension:

(new Generator())->withMaybe(0)->ext(\Faker\Extension\FileExtension::class)->mimeType()

throws Call to a member function mimeType() on null. This is because withMaybe(0) returns the DefaultGenerator, which overloads ext() to return null.

@Nyholm
Copy link
Member Author

Nyholm commented Dec 22, 2020

Excellent @krsriq, You are correct.

That is something I have not thought about. How do you suggest we fix that?

src/Faker/Generator.php Outdated Show resolved Hide resolved
src/Faker/Generator.php Outdated Show resolved Hide resolved

public function __construct()
{
$this->uniqueGenerator = new UniqueGenerator($this);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of reimplementing the behaviour here, what do you think about moving methods from Faker\Provider\Base to Faker\Generator one by one, guided by tests?

Also see #233.

@krsriq
Copy link

krsriq commented Dec 23, 2020

Excellent @krsriq, You are correct.

That is something I have not thought about. How do you suggest we fix that?

We have a related problem here in withUnique:

$generator->withUnique()->ext(\Faker\Extension\FileExtension::class)->mimeType()

may return duplicate results.

The issue here is that the UniqueGenerator stores the called method name and result in $uniques to check on a subsequent call if the result is unique. The method name in the case above, though, is ext, the result the extension class \Faker\Core\File.

Unfortunately I have not yet found a solution for these problems, I'll keep digging..

@krsriq
Copy link

krsriq commented Jan 7, 2021

@Nyholm okay, I found a way to do this for the UniqueGenerator, DefaultGenerator and ValidGenerator, though it's not pretty:

we basically want to be able to differentiate between a call to ext on those generators and the other method calls.
With this solution a call to ext temporarily stores the extension the method should be called on on the generator class, then returns the generator, so when finally the actual method is called on the generator, we can forward the call to the correct extension.

This is just a proof-of-(a-bad-)concept and could definitely be improved (or a cleaner solution be found), but it means that it's not impossible to use extensions with these generators.

@pimjansen
Copy link

What are the plans with this? Since this is crucial on the design right?

@pimjansen
Copy link

@Nyholm @krsriq did you already dive into this?

@Nyholm Nyholm force-pushed the modifiers branch 2 times, most recently from 4d79099 to 07f511a Compare August 8, 2021 02:30
@Nyholm
Copy link
Member Author

Nyholm commented Aug 8, 2021

I think I've solved the extension stuff. Please have a look.

I took @krsriq idea and continued working on it.

@pimjansen
Copy link

pimjansen commented Dec 18, 2021

I think the usecase is not resolved yet:

for ($i=0; $i<6;$i++) {
    echo $faker->unique()->ext(\Faker\Extension\BloodExtension::class)->bloodGroup().PHP_EOL;
}
A+
AB+
AB+
AB-
O+
O+

@Nyholm am i missing something here?

@bram-pkg
Copy link
Member

Excellent @krsriq, You are correct.
That is something I have not thought about. How do you suggest we fix that?

We have a related problem here in withUnique:

$generator->withUnique()->ext(\Faker\Extension\FileExtension::class)->mimeType()

may return duplicate results.

The issue here is that the UniqueGenerator stores the called method name and result in $uniques to check on a subsequent call if the result is unique. The method name in the case above, though, is ext, the result the extension class \Faker\Core\File.

Unfortunately I have not yet found a solution for these problems, I'll keep digging..

This has been fixed now.

@bram-pkg
Copy link
Member

bram-pkg commented Jan 18, 2022

The issue with ->unique()->ext() seems to have been fixed.

@pimjansen
Copy link

LGTM

What does the rest think? I think this is the last topic before splitting it to seperate language packs right?

@bram-pkg bram-pkg merged commit fa135b4 into FakerPHP:main Jan 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants