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

Add 'with' to allow chaining of methods #5

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Ben-Russell
Copy link

This will allow use such as:

(new UserStory)->with(['isAdmin'])->create([ 'Full Name' => 'Ben Russell' ]);

Where your story looks like:

class UserStory extends FactoryStory
{
    public function build($params = [])
    {
        return factory(User::class)->create($params);
    }
    public function isAdmin(User $user)
    {
        $user->isAdmin = true;
        $user->save();
        return $user;
    }
}

This should let you create story "states" kinda similar to factory "states".

Let me know if you like the idea and have any suggestions or feel free to take it and implement a different way. Just currently I seem to have to make a new story for each different state, and would really like this kind of functionality in my project.

sasin91 and others added 3 commits July 17, 2017 10:26
*note haven't tested it, due to being on my phone.
Cleaning the create() method on the FactoryStory::class
@jeffochoa
Copy link
Owner

The idea is cool, but i think the problem described in your example could be solved just by using model factory states.

I the other hand, you can pass in the "params" array something like ['is_admin' => true ] and then handle that situation in the build() of the story class.

Do you have any other user case?

@Ben-Russell
Copy link
Author

Yeah, to keep my example short, you are right that they could be done in model factory states.

One main use for factory stories I am doing is for different states of a shopping cart. I use the factory story to attach different relationships to the cart that I couldn't in a model factory, as well as other logic that's needed to create a working cart. So currently I have different factory stories for cart states such as a cart that is ready to start going through the checkout of choosing shipping options and one that has already gone through this process. Instead of having to nest a factory story, I was hoping to just be able to use one factory story, with states.

I hope that makes sense. Let me know if you have another question.

@stephanecoinon
Copy link
Contributor

Even though states can be handled via a model factory, I think FactoryStory should too for the convenience that build() brings. However I think the method should be called states() instead of with() to mimic the model factory method .

So to reuse Ben's example, I suggest:

(new UserStory)->states('admin')->create([ 'Full Name' => 'Ben Russell' ]);

where the story is:

class UserStory extends FactoryStory
{
    public function build($params = [])
    {
        return $this->factory(User::class)->create($params);
    }
 }

and we add something like this to FactoryStory (untested) to delegate the states handling to the model factory:

class FactoryStory
{
    protected $states = [];

    // ...

    public function states($states)
    {
        $this->states = is_array($states) ? $states : func_get_args();

        return $this;
    }

    public function factory()
    {
        return factory(func_get_args())->states($this->states);
    } 

    //...
}

then you just define the actual "admin" state in the model factory allowing it to be used by both the model factory and FactoryStory

the other advantage is that FactoryStory::factory() gives us a hook to modify the call to the model factory on the fly, maybe we could use that to handle times() as well

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.

4 participants