Skip to content
This repository has been archived by the owner on Aug 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1 from localheinz/feature/provider
Browse files Browse the repository at this point in the history
Enhancement: Add interface and finder
  • Loading branch information
localheinz authored May 25, 2017
2 parents 740095e + 39d8381 commit 7550bfa
Show file tree
Hide file tree
Showing 18 changed files with 665 additions and 5 deletions.
4 changes: 3 additions & 1 deletion .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ EOF;

$config = Config\Factory::fromRuleSet(new Config\RuleSet\Php56($header));

$config->getFinder()->in(__DIR__);
$config->getFinder()
->in(__DIR__)
->exclude('test/Unit/Asset/Definition/CanNotBeAutoloaded');

$cacheDir = \getenv('TRAVIS') ? \getenv('HOME') . '/.php-cs-fixer' : __DIR__;

Expand Down
74 changes: 73 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
[![Latest Stable Version](https://poser.pugx.org/localheinz/factory-girl-definition/v/stable)](https://packagist.org/packages/localheinz/factory-girl-definition)
[![Total Downloads](https://poser.pugx.org/localheinz/factory-girl-definition/downloads)](https://packagist.org/packages/localheinz/factory-girl-definition)

Provides an interface for, and an easy way to find and register entity definitions for [`breerly/factory-girl-php`](https://github.com/breerly/factory-girl-php).

## Installation

Run
Expand All @@ -17,7 +19,77 @@ $ composer require localheinz/factory-girl-definition

## Usage

:bulb: This is a great place for showing a few usage examples!
### Create Definitions

Implement the `Definition` interface and use the instance of `FactoryGirl\Provider\Doctrine\FixtureFactory`
that is passed in into `accept()` to define entities:

```php
<?php

namespace Foo\Bar\Test\Fixture\Entity;

use FactoryGirl\Provider\Doctrine\FixtureFactory;
use Foo\Bar\Entity;
use Localheinz\FactoryGirl\Definition\Definition;

final class UserProvider implements Definition
{
public function accept(FixtureFactory $fixtureFactory)
{
$fixtureFactory->defineEntity(Entity\User::class, [
// ...
]);
}
}
```

:bulb: Any number of entities can be defined within a definition.
However, it's probably a good idea to create a definition for each entity.

### Register Definitions

Lazily instantiate an instance of `FactoryGirl\Provider\Doctrine\FixtureFactory`
and use `Definitions` to find definitions and register them with the factory:

```php
<?php

namespace Foo\Bar\Test\Integration;

use Doctrine\ORM;
use FactoryGirl\Provider\Doctrine\FixtureFactory;
use Localheinz\FactoryGirl\Definition\Definitions;
use PHPUnit\Framework;

abstract class AbstractIntegrationTestCase extends Framework\TestCase
{
/**
* @return ORM\EntityManager
*/
final protected function entityManager()
{
// ...
}

/**
* @return FixtureFactory
*/
final protected function fixtureFactory()
{
static $fixtureFactory = null;

if (null === $fixtureFactory) {
$fixtureFactory = new Doctrine\FixtureFactory($entityManager);
$fixtureFactory->persistOnGet(true);

Definitions::in(__DIR__ . '/../Fixture')->registerWith($fixtureFactory);
}

return $fixtureFactory;
}
}
```

## Contributing

Expand Down
14 changes: 11 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "localheinz/factory-girl-definition",
"description": "Provides an interface and a finder for definitions with breerly/factory-girl-php.",
"description": "Provides an interface for, and an easy way to find and register entity definitions for breerly/factory-girl-php.",
"type": "library",
"license": "MIT",
"authors": [
Expand All @@ -13,13 +13,21 @@
"preferred-install": "dist",
"sort-packages": true
},
"minimum-stability": "beta",
"prefer-stable": true,
"require": {
"php": "^5.6 || ^7.0"
"php": "^5.6 || ^7.0",
"zendframework/zend-file": "^2.7.1"
},
"require-dev": {
"breerly/factory-girl-php": "^1.0.0",
"codeclimate/php-test-reporter": "0.4.4",
"localheinz/php-cs-fixer-config": "1.2.1",
"phpunit/phpunit": "^5.7.20"
"phpunit/phpunit": "^5.7.20",
"refinery29/test-util": "^0.11.3"
},
"suggest": {
"breerly/factory-girl-php": "For creating a fixture factory the definitions can be used with."
},
"autoload": {
"psr-4": {
Expand Down
Empty file removed src/.gitkeep
Empty file.
19 changes: 19 additions & 0 deletions src/Definition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition;

use FactoryGirl\Provider\Doctrine\FixtureFactory;

interface Definition
{
public function accept(FixtureFactory $fixtureFactory);
}
87 changes: 87 additions & 0 deletions src/Definitions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition;

use FactoryGirl\Provider\Doctrine\FixtureFactory;
use Zend\File;

final class Definitions
{
/**
* @var Definition[]
*/
private $definitions = [];

private function __construct()
{
}

/**
* @param string $directory
*
* @throws Exception\InvalidDirectory
* @throws Exception\InvalidDefinition
*
* @return self
*/
public static function in($directory)
{
if (!\is_string($directory)) {
throw Exception\InvalidDirectory::notString($directory);
}

if (!\is_dir($directory)) {
throw Exception\InvalidDirectory::notDirectory($directory);
}

$locator = new File\ClassFileLocator($directory);

/** @var File\PhpClassFile[] $files */
$files = \iterator_to_array($locator);

$instance = new self();

foreach ($files as $file) {
foreach ($file->getClasses() as $className) {
try {
$reflection = new \ReflectionClass($className);
} catch (\ReflectionException $exception) {
continue;
}

if (!$reflection->isSubclassOf(Definition::class) || $reflection->isAbstract()) {
continue;
}

try {
$definition = $reflection->newInstance();
} catch (\Exception $exception) {
throw Exception\InvalidDefinition::fromClassNameAndException(
$className,
$exception
);
}

$instance->definitions[] = $definition;
}
}

return $instance;
}

public function registerWith(FixtureFactory $fixtureFactory)
{
foreach ($this->definitions as $definition) {
$definition->accept($fixtureFactory);
}
}
}
33 changes: 33 additions & 0 deletions src/Exception/InvalidDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition\Exception;

final class InvalidDefinition extends \RuntimeException
{
/**
* @param string $className
* @param \Exception $exception
*
* @return self
*/
public static function fromClassNameAndException($className, \Exception $exception)
{
return new self(
\sprintf(
'An exception was thrown while trying to instantiate definition "%s".',
$className
),
null,
$exception
);
}
}
41 changes: 41 additions & 0 deletions src/Exception/InvalidDirectory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition\Exception;

final class InvalidDirectory extends \InvalidArgumentException
{
/**
* @param mixed $directory
*
* @return self
*/
public static function notString($directory)
{
return new self(\sprintf(
'Directory should be a string, got %s instead.',
\is_object($directory) ? \get_class($directory) : \gettype($directory)
));
}

/**
* @param string $directory
*
* @return self
*/
public static function notDirectory($directory)
{
return new self(\sprintf(
'Directory should be a directory, but "%s" is not.',
$directory
));
}
}
26 changes: 26 additions & 0 deletions test/Unit/Asset/Definition/Acceptable/UserDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition\Test\Unit\Asset\Definition\Acceptable;

use FactoryGirl\Provider\Doctrine\FixtureFactory;
use Localheinz\FactoryGirl\Definition\Definition;

/**
* Is acceptable as it implements the ProviderInterface.
*/
final class UserDefinition implements Definition
{
public function accept(FixtureFactory $factory)
{
$factory->defineEntity('Foo');
}
}
26 changes: 26 additions & 0 deletions test/Unit/Asset/Definition/CanNotBeAutoloaded/UserDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition\Test\Unit\Asset\Definition\CanNotBeAutoloaded;

use FactoryGirl\Provider\Doctrine\FixtureFactory;
use Localheinz\FactoryGirl\Definition\Definition;

/**
* Is not acceptable as it can not be autoloaded (class name does not match file name).
*/
final class MaybeUserDefinition implements Definition
{
public function accept(FixtureFactory $factory)
{
$factory->defineEntity('Foo');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* Copyright (c) 2017 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @link https://github.com/localheinz/factory-girl-definition
*/

namespace Localheinz\FactoryGirl\Definition\Test\Unit\Asset\Definition\DoesNotImplementInterface;

use FactoryGirl\Provider\Doctrine\FixtureFactory;

/**
* Is not acceptable as it does not implement the DefinitionInterface.
*/
final class UserDefinition
{
public function accept(FixtureFactory $factory)
{
$factory->defineEntity('Foo');
}
}
Loading

0 comments on commit 7550bfa

Please sign in to comment.