Skip to content

Instantly share code, notes, and snippets.

@dantleech
Last active May 20, 2024 07:13

Revisions

  1. dantleech revised this gist May 20, 2024. No changes.
  2. dantleech revised this gist May 19, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 10_Builder.php
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@

    /**
    * Builder classes are registed in the "FixtureContainer" and provide fixtures
    * based on the `__invoke` return type.
    * based on the `__invoke` return type (not sure if that's a great idea).
    */
    final class ProjectBuilder
    {
  3. dantleech revised this gist May 19, 2024. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions 10_Builder.php
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,7 @@ public function __invoke(
    {
    return new Project(
    Uuid::v4(),
    // _get_ (or create) the organisation instance
    $container->get(Organisation::class, $organisation),
    $name
    );
  4. dantleech revised this gist May 19, 2024. 1 changed file with 43 additions and 0 deletions.
    43 changes: 43 additions & 0 deletions 20_FixtureContainer.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    <?php

    final class FixtureContainer
    {
    /**
    * @var array<string,array<string,\Closure():object>>
    */
    private array $factories = [];

    /**
    * @var array<string,array<string,object>>
    */
    private array $instances = [];

    /**
    * @param list<object> $builders
    */
    public function __construct(
    private array $builders
    )
    {
    }

    /**
    * @template TClass of object
    * @param class-string<TClass> $className
    * @return TClass
    */
    public function get(string $className, string $identifier): object
    {
    // blah...
    return $instance;
    }

    /**
    * @param class-string $className
    * @param array<string,mixed> $params
    */
    public function register(string $className, string $identifier, array $params = []): void
    {
    // blah...
    }
    }
  5. dantleech revised this gist May 19, 2024. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions 10_Builder.php
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,9 @@
    <?php

    /**
    * Builder classes are registed in the "FixtureContainer" and provide fixtures
    * based on the `__invoke` return type.
    */
    final class ProjectBuilder
    {
    public function __invoke(
  6. dantleech revised this gist May 19, 2024. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
  7. dantleech created this gist May 19, 2024.
    18 changes: 18 additions & 0 deletions Builder.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    <?php

    final class ProjectBuilder
    {
    public function __invoke(
    FixtureContainer $container,
    string $name,
    string $organisation
    ): Project
    {
    return new Project(
    Uuid::v4(),
    $container->get(Organisation::class, $organisation),
    $name
    );
    }
    }

    40 changes: 40 additions & 0 deletions Context.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    <?php

    class OrganisationContext implements Context
    {
    /**
    * Fixture container is similar to a service container, but for class instances.
    */
    public function __construct(private FixtureContainer $fixture)
    {
    }

    #[Given('I have an organisation :name')]
    public function iHaveAnOrganisation(string $name): void
    {
    // register a _named_ fixture for this class
    // a _Builder_ must be registered for the class and the parameters
    // are passed to its __invoke method
    $this->fixture->register(Organisation::class, $name, [
    'name' => $name
    ]);
    }

    #[Given('I have a project :project in organisation :organisation')]
    public function iHaveAProject(string $project, string $organisation): void
    {
    // the Builders also get the FixtureContainer so can retrieve dependencies
    // (in this case the organisation by the name we previously registered)
    $this->fixture->register(Project::class, $project, [
    'name' => $project,
    'organisation' => $organisation
    ]);
    }

    #[When('I upload an artifact to project :name')]
    public function iUploadAnArtifactToThatProject(string $project): void
    {
    // calling `get` will lazily invoke the Builders
    $project = $this->fixture->get(Project::class, $project);
    }
    }