PHP code example of buildotter / php-core

1. Go to this page and download the library: Download buildotter/php-core library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

buildotter / php-core example snippets


anElephant()->with(
    name: 'Elmer',
    birth: new \DateTimeImmutable(),
);

anElephant()->with([
    'name' => 'Elmer',
    'birth' => new \DateTimeImmutable(),
]);

namespace App\Entity;

final class Elephant
{
    public function __construct(
        private Uuid $id,
        private string $name,
        private \DateTimeImmutable $birth,
        /** @var Topic[] */
        private array $topics = [],
    ) {}
}

namespace App\Fixtures\Builder;

use App\Entity\Elephant;
use App\Entity\Topic;
use Buildotter\Core\Buildatable;
use Buildotter\Core\BuildableWithArgUnpacking;

/**
 * @implements Buildatable<Elephant>
 */
final readonly class ElephantBuilder implements Buildatable
{
    use BuildableWithArgUnpacking;

    public function __construct(
        private Uuid $id,
        private string $name,
        private \DateTimeImmutable $birth,
        /** @var Topic[] */
        private array $topics,
    ) {}

    public static function new(): self
    {
        $random = \random();

        // Note that we try to use commonly used or safe values.
        return new self(
            new Uuid(),
            $random->name(),
            \DateTimeImmutable::createFromMutable($random->dateTimeBetween('-50 years', 'now')),
            // You may see here that it may be necessary to build multiple objects sometimes.
            \someTopics($random->numberBetween(0, 10)),
        );
    }

    public function build(): Elephant
    {
        return new Elephant(
            $this->id,
            $this->name,
            $this->birth,
            $this->topics
        );
    }

    // Providing domain specific methods instead of only relying on the `with()` method
    // allows you to focus on what is important in your tests.
    // It helps to make your tests more readable and maintainable.
    //
    // Note here that we did not find the need to implement a domain specific method
    // to change the `$topics` property.
    // We may rely on the `with()` method as long as we don't find useful to have
    // a method like `interestedInTopics(array $topics)` or whatever.

    public function named(string $name): self
    {
        return $this->with(name: $name);
    }

    public function bornThe(\DateTimeImmutable|string $birth): self
    {
        return $this->with(birth: $birth instanceof \DateTimeImmutable ? $birth : \DateTimeImmutable::createFromFormat('Y-m-d', $birth));
    }

    public function yearsOld(int $age): self
    {
        if ($age <= 0) {
            throw new \InvalidArgumentException('Age must be positive');
        }

        return $this->with(birth: new \DateTimeImmutable(\sprintf('-%d years', $age)));
    }

    public function minor(): self
    {
        return $this->yearsOld(\random()->numberBetween(1, 17));
    }
}


use App\Fixtures\Builder\ElephantBuilder;
use App\Fixtures\Builder\TopicBuilder;

function random(): \Faker\Generator
{
    return \Faker\Factory::create();
}

function anElephant(): ElephantBuilder
{
    return ElephantBuilder::new();
}

/**
 * @return App\Entity\Elephant[]
 */
function someElephants(int|null $numberOfItems = null): array
{
    return Many::from(ElephantBuilder::class, $numberOfItems);
}

function aTopic(): TopicBuilder
{
    return TopicBuilder::new();
}

/**
 * @return App\Entity\Topic[]
 */
function someTopics(int|null $numberOfItems = null): array
{
    return Many::from(TopicBuilder::class, $numberOfItems);
}

use PHPUnit\Framework\TestCase;

final class RentBookTest extends TestCase
{
    public function test_a_minor_cannot_rent_a_book_for_adult(): void
    {
        $minor = \anElephant()->minor()->build();

        expectException(UnderAgeException::class);

        (new RentBook())($minor, \aBook()->forAdult()->build());
    }
}